设计模式--委派模式与模板方法模式

委派模式

委派模式(Delegate Pattern)又叫委托模式,是一种面向对象的设计模式,允许对象组合实现与继承相同的代码重用。它的基本作用就是负责任务的调用和分配任务,是一种特殊的静态代理,可以理解为全权代理,但是代理模式注重过程,而委派模式注重结果。委派模式属于行为模式,不属于GOF 23种设计模式。

java 复制代码
import java.util.HashMap;
import java.util.Map;

interface IEmployee{
    void doing(String task);
}
class EmployeeA implements IEmployee{
    protected String goodAt = "编程";
    @Override
    public void doing(String task) {
        System.out.println("我是员工A,我擅长"+goodAt+",现在开始做"+task+"工作");
    }
}

class EmployeeB implements IEmployee{
    protected String goodAt = "平面设计";
    @Override
    public void doing(String task) {
        System.out.println("我是员工A,我擅长"+goodAt+",现在开始做"+task+"工作");
    }
}

class Leader implements IEmployee{
    private Map<String, IEmployee> employee = new HashMap<>();

    public Leader(){
        employee.put("爬虫",new EmployeeA());
        employee.put("海报图",new EmployeeB());
    }

    @Override
    public void doing(String task) {
        if(!employee.containsKey(task)){
            System.out.println("这个任务"+task+"超出我的能力范围");
            return;
        }
        employee.get(task).doing(task);
    }
}

class Boss{
    public void command(String task, Leader leader){
        leader.doing(task);
    }
}

public class Test {
    public static void main(String[] args) {
        new Boss().command("海报图",new Leader());
    }
}

在JDK中有一个典型的委派,JVM在加载类是用的双亲委派模型。

委派模式的优缺点:

优点:通过任务委派能够将一个大型的任务细化,然后通过同一管理这些子任务的完成情况实现任务的跟进,能够加快任务执行的效率。

缺点:任务委派方式需要根据任务的复杂程度进行不同的改变,在任务比较复杂的情况下可能需要进行多重委派,容易造成混乱。

模板方法模式

模板方法模式(Template Method Pattern)又叫模板模式,是指定义一个操作中的算法框架,而将一些步骤延迟到子类中。使得子类可以不改变一个算法的结构即可重定义该算法的某些特定步骤,属于行为型设计模式。

模板方法模式实际上是封装了一个固定流程,该流程由几个步骤组成,具体步骤可以由子类进行不同实现,从而让固定的流程产生不同的结果。它非常简单,其实就是类的继承机制,但它却是一个应用非常广泛的模式。

利用模板方法重构JDBC操作:

java 复制代码
import lombok.Data;

import javax.sql.DataSource;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.List;

/**
 * ORM映射定制化接口
 */
interface RowMapper<T>{
    T mapRow(ResultSet rs, int rowNum) throws Exception;
}

abstract class JdbcTemplate{
    private DataSource dataSource;

    public JdbcTemplate(DataSource dataSource) {
        this.dataSource = dataSource;
    }

    public final List<?> executeQuery(String sql, RowMapper<?> rowMapper, Object[] values){
        try{
            //1.获取连接
            Connection conn = this.getConnection();
            //2.创建语句集
            PreparedStatement pstm = this.createPrepareStatement(conn,sql);
            //3.执行语句
            ResultSet rs = this.executeQuery(pstm, values);
            //4.处理结果
            List<?> result = this.parseResultSet(rs,rowMapper);
            //5.关闭结果集
            rs.close();
            //6.关闭语句集
            pstm.close();
            //7.关闭连接
            conn.close();
            return result;
        }catch (Exception e){
            e.printStackTrace();
        }
        return null;
    }

    private List<?> parseResultSet(ResultSet rs, RowMapper<?> rowMapper) throws Exception {
        List<Object> result = new ArrayList<>();
        int rowNum = 0;
        while(rs.next()){
            result.add(rowMapper.mapRow(rs,rowNum++));
        }
        return result;
    }

    private ResultSet executeQuery(PreparedStatement pstm, Object[] values) throws SQLException {
        for(int i=0;i<values.length;i++){
            pstm.setObject(i,values);
        }
        return pstm.executeQuery();
    }
    private PreparedStatement createPrepareStatement(Connection conn, String sql) throws SQLException {
        return conn.prepareStatement(sql);
    }

    private Connection getConnection() throws SQLException {
        return this.dataSource.getConnection();
    }

}

/**
 * 创建实体对象
 */
@Data
class  Member{
    private String username;
    private String password;
    private String nickname;
    private int age;
    private String addr;
}

/**
 * 数据库操作类
 */
class MemberDao extends JdbcTemplate{

    public MemberDao(DataSource dataSource) {
        super(dataSource);
    }

    public List<?> selectAll(){
        String sql = "select * from t_member";
        return super.executeQuery(sql, new RowMapper<Member>() {
            @Override
            public Member mapRow(ResultSet rs, int rowNum) throws Exception {
                Member member = new Member();
                member.setUsername(rs.getString("username"));
                member.setPassword(rs.getString("password"));
                member.setAge(rs.getInt("age"));
                member.setAddr(rs.getString("addr"));
                return member;
            }
        },null);
    }
}

public class Test {
    public static void main(String[] args) {
        MemberDao memberDao = new MemberDao(null);
        List<?> result = memberDao.selectAll();
        System.out.println(result);
    }
}

模板方法模式的优缺点:

优点:

  1. 利用模板方法将相同处理逻辑的代码放到抽象父类中,可以提高代码的复用性。
  2. 将不同的代码不同的子类中,通过对子类的扩展增加新的行为,提高代码的扩展性。
  3. 把不变的行为写在父类上,去除子类大重复代码,提供一个很好的代码复用平台,符合开闭原则

缺点:

  1. 类数目的增加,每一个抽象类都需要一个子类来实现,这样导致类的个数增加。
  2. 类数量的增加,间接地增加了系统实现的复杂度。
  3. 继承关系自身缺点,如果父类添加新的抽象方法,所有子类都要改一遍。
相关推荐
达文汐2 分钟前
【困难】力扣算法题解析LeetCode332:重新安排行程
java·数据结构·经验分享·算法·leetcode·力扣
培风图南以星河揽胜3 分钟前
Java版LeetCode热题100之零钱兑换:动态规划经典问题深度解析
java·leetcode·动态规划
启山智软26 分钟前
【中大企业选择源码部署商城系统】
java·spring·商城开发
我真的是大笨蛋29 分钟前
深度解析InnoDB如何保障Buffer与磁盘数据一致性
java·数据库·sql·mysql·性能优化
怪兽源码1 小时前
基于SpringBoot的选课调查系统
java·spring boot·后端·选课调查系统
恒悦sunsite1 小时前
Redis之配置只读账号
java·redis·bootstrap
梦里小白龙1 小时前
java 通过Minio上传文件
java·开发语言
人道领域1 小时前
javaWeb从入门到进阶(SpringBoot事务管理及AOP)
java·数据库·mysql
sheji52612 小时前
JSP基于信息安全的读书网站79f9s--程序+源码+数据库+调试部署+开发环境
java·开发语言·数据库·算法
毕设源码-邱学长2 小时前
【开题答辩全过程】以 基于Java Web的电子商务网站的用户行为分析与个性化推荐系统为例,包含答辩的问题和答案
java·开发语言