设计模式——组合模式、委派模式、模板方法模式

组合模式(Composite Pattern)

定义:组合模式也成为整体--部分模式,宗旨是通过将单个对象和组合对象用相同的接口进行表示。使客户端对单个对象和组合对象保持一致的方式处理。属于结构型模式。

适用场景:希望客户端可以忽略组合对象和单个对象的差异时;对象层次具备整体和部分,呈树形结构时。

委派模式(Delegate Pattern)

定义:委派模式又称委托模式,基本作用是负责任务的调度和任务分配,将任务的分配和执行分离开来,可以看做是一种特殊情况下的静态代理的全权处理。属于行为型模式,不是GOF 23种设计模式之一。

适用场景:委派对象本身不清楚如何处理一个任务,把任务交给其他对象处理。

优点:通过任务委派可以将大型任务细化,统一管理子任务,将任务分配和执行分离,避免类的臃肿。

委派模式和代理模式区别:

1) 委派模式是行为型模式,代理模式是结构型模式;
2) 委派模式注重任务分配,注重结果;代理模式注重的是功能增强,注重过程;
3) 委派模式是一种特殊的静态代理,相当于全权代理;

在源码中Method、ClassLoader、BeanDefinition、DispatcherServlet都有用到委派模式来分配任务由其他对象执行。

模板方法模式(Template Method Pattern)

定义:模板方法模式又称模板模式,是指定义一个算法的骨架,并允许子类为其中一个或多个步骤提供实现。模板模式可以使子类在不改变算法结构的情况下,重新定义算法的实现;属于行为性模式。

适用场景:一般应用于算法,将固定部分实现,将可变的行为留给子类来实现;将各子类中公共的行为提取出来集中在一个公共的父类中,从而避免代码重复。

优点:

1) 模板模式将相同处理逻辑代码抽取到抽象父类中,去除了子类重复代码,提高代码复用性;
2) 将不同的代码放在子类中,通过对子类的扩展增加新的行为,提高代码可扩展性;

缺点:

1) 每个抽象类都需要一个子类来实现,导致类数量增加,也增加了系统复杂度;
2) 如果父类添加新的抽象方法,所有子类都需要修改去实现;所以如果步骤不稳定,频繁改变不适合使用模板模式;

在spring-jdbc框架中,就用到了模板模式,JdbcTemplate中定义了连接数据库查询的框架结构和方法,而查询结果集如何映射给用户查询的entity对象,声明了一个钩子方法rowMapper.mapRow(rs, rowNumber)由调用方来自己实现:

public class JdbcTemplate extends JdbcAccessor implements JdbcOperations {
    public <T> List<T> query(String sql, RowMapper<T> rowMapper) throws DataAccessException {
        return (List)result(this.query((String)sql, (ResultSetExtractor)(new RowMapperResultSetExtractor(rowMapper))));
    }

    public <T> T query(final String sql, final ResultSetExtractor<T> rse) throws DataAccessException {
        class QueryStatementCallback implements StatementCallback<T>, SqlProvider {
            QueryStatementCallback() {}

            @Nullable
            public T doInStatement(Statement stmt) throws SQLException {
                ResultSet rs = null;
                Object var3;
                try {
                    rs = stmt.executeQuery(sql);
                    var3 = rse.extractData(rs);
                } finally {
                    JdbcUtils.closeResultSet(rs);
                }
                return var3;
            }

            public String getSql() {
                return sql;
            }
        }

        return this.execute((StatementCallback)(new QueryStatementCallback()));
    }
}
@FunctionalInterface
public interface RowMapper<T> {
    @Nullable
    T mapRow(ResultSet var1, int var2) throws SQLException;
}
public class RowMapperResultSetExtractor<T> implements ResultSetExtractor<List<T>> {
    private final RowMapper<T> rowMapper;
    private final int rowsExpected;
    public List<T> extractData(ResultSet rs) throws SQLException {
        List<T> results = this.rowsExpected > 0 ? new ArrayList(this.rowsExpected) : new ArrayList();
        int var3 = 0;
        while(rs.next()) {
            results.add(this.rowMapper.mapRow(rs, var3++));
        }
        return results;
    }
}

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值