设计模式之模板方法封装

来源:互联网 发布:乐心手环数据清零 编辑:程序博客网 时间:2024/05/20 08:44

在日常开发中,经常在使用第三方的开源框架时,需要配置一些环境变量,然后正常的执行我们所有的方法,然后再进行一些资源回收的工作,如果每次在调用的过程中,我们都这么去设置,那冗余的代码就会很多。
通常我们会对这一类资源的调用采用工具类进行包装,例子如下:

 /**     * 执行set操作     *      * @param key     * @param value     * @return     */    public String set( String key,String value) {        ShardedJedis shardedJedis = null;        try {            // 从连接池中获取到jedis分片对象            shardedJedis = shardedJedisPool.getResource();            return shardedJedis.set(key, value);        } catch (Exception e) {            e.printStackTrace();        } finally {            if (null != shardedJedis) {                // 关闭,检测连接是否有效,有效则放回到连接池中,无效则重置状态                shardedJedis.close();            }        }        return null;    }    /**     * 执行get操作     *      * @param key     * @param value     * @return     */    public String get(String key) {        ShardedJedis shardedJedis = null;        try {            // 从连接池中获取到jedis分片对象            shardedJedis = shardedJedisPool.getResource();            return shardedJedis.get(key);        } catch (Exception e) {            e.printStackTrace();        } finally {            if (null != shardedJedis) {                // 关闭,检测连接是否有效,有效则放回到连接池中,无效则重置状态                shardedJedis.close();            }        }        return null;    }

这个是对调用Redis的一个get/set方法的封装,从语法逻辑上看没什么问题,但是方法中存在很多相同的代码,最终执行的方法不同,类似于模板。下面讲解下怎么通过模板设计模式对这段代码进行封装。
1.新增一个接口,该接口包含一个回调方法

public interface Function<T, E> {    public T callback(E e);}
说明:接口的第一个参数为目标执行方法的返回值,第二个参数为目标方法的句柄

2.模板方法,方法的参数是步骤1中的接口

private <T> T execute(Function<T, ShardedJedis> fun) {        ShardedJedis shardedJedis = null;        try {            // 从连接池中获取到jedis分片对象            shardedJedis = shardedJedisPool.getResource();            return fun.callback(shardedJedis);        } catch (Exception e) {            e.printStackTrace();        } finally {            if (null != shardedJedis) {                // 关闭,检测连接是否有效,有效则放回到连接池中,无效则重置状态                shardedJedis.close();            }        }        return null;    }

说明:方法的参数为步骤1中的接口,在模板方法中编写好整个模板方法的步骤

3.真正需要调用的方法

public String set(final String key, final String value) {        return this.execute(new Function<String, ShardedJedis>() {            @Override            public String callback(ShardedJedis e) {                return e.set(key, value);            }        });    }

说明:调用步骤2中的方法,由于步骤2的入参是一个接口,所以默认实现一个匿名类接口,在接口中通过句柄调用真正要执行的方法。

原创粉丝点击