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

委派模式

委派模式(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. 继承关系自身缺点,如果父类添加新的抽象方法,所有子类都要改一遍。
相关推荐
懂得节能嘛.1 分钟前
【动态配置中心】Java+Redis构建动态配置中心
java·开发语言·redis
专注于大数据技术栈2 分钟前
Java中JDK、JRE、JVM概念
java·开发语言·jvm
YuanlongWang6 分钟前
C# 基础——值类型与引用类型的本质区别
java·jvm·c#
Kay_Liang30 分钟前
大语言模型如何精准调用函数—— Function Calling 系统笔记
java·大数据·spring boot·笔记·ai·langchain·tools
自由的疯1 小时前
Java 如何学习Docker
java·后端·架构
自由的疯1 小时前
Java Docker本地部署
java·后端·架构
007php0071 小时前
猿辅导Java面试真实经历与深度总结(二)
java·开发语言·python·计算机网络·面试·职场和发展·golang
摇滚侠1 小时前
Spring Boot 3零基础教程,WEB 开发 内容协商机制 笔记34
java·spring boot·笔记·缓存
一勺菠萝丶1 小时前
在 macOS 上用 Docker 为 Java 后端 & 常见开发需求搭建完整服务(详尽教程)
java·macos·docker
顾漂亮1 小时前
JVM底层攻坚
java·jvm·spring