emanjusaka —— 彼岸花开可奈何

彼岸花开可奈何

设计模式在源码中的应用——建造者模式

2024-06-14

by emanjusaka from https://www.emanjusaka.top/2024/06/design-pattern-builder-pattern 彼岸花开可奈何

本文为原创文章,可能会更新知识点以及修正文中的一些错误,全文转载请保留原文地址,避免未即时修正的错误误导。

建造者模式(Builder Pattern)是一种创建型设计模式,它允许你通过一步步构造创建复杂的对象。这种模式将对象的构建过程与表示分离,从而使得相同的构建过程可以创建不同的表示。建造者模式通常包括以下四个角色:

  1. 产品(Product): 定义了复杂对象的结构和组成成分的接口或抽象类。 例如,在构建一个电脑对象时,产品可以定义为Computer类,包含如CPU、内存、硬盘等组件。

  2. 抽象建造者(Builder): 定义了一个创建产品对象的接口,但不涉及具体的产品表示。 这个接口声明了所有用来构造型的方法,如setCPU(), setMemory()等,但并不提供这些方法的具体实现。

  3. 具体建造者(Concrete Builder): 实现了抽象建造者接口,负责构造并逐步构建产品的各个部分。 每个具体建造者都对应一种具体的产品表示。 继承自抽象建造者,提供了具体的产品组建设置方法的实现。

  4. 指挥者(Director): 负责安排复杂对象的建造步骤顺序。 构建一个使用Builder接口的对象,导演类隔离了客户端与建造过程的细节,客户端只需调用导演类的构建方法即可得到完整的产品对象。

上面给出的是建造者模式的经典结构,实际应用中根据需要可以简化掉抽象建造者和指挥者。

Mybatis 源码中的建造者模式应用

这是 mybatis 源码中一个应用建造者模式的例子,下面的代码是经过简化之后的。

 package top.emanjusaka.mybatis.mapping;
 ​
 import top.emanjusaka.mybatis.session.Configuration;
 ​
 import java.util.Map;
 ​
 /**
  * @Author emanjusaka
  * @Date 2024/6/13 12:29
  * @Version 1.0
  * 映射语句类
  */
 @Data
 public class MappedStatement {
     private Configuration configuration;
     private String id;
     private SqlCommandType sqlCommandType;
 ​
     private String parameterType;
     private String resultType;
     private String sql;
     private Map<Integer,String> parameter;
 ​
     public MappedStatement() {
     }
     /**
      * 建造者
      */
     public static class Builder {
         private MappedStatement mappedStatement = new MappedStatement();
         public Builder(Configuration configuration, String id,SqlCommandType sqlCommandType, String parameterType,String resultType, String sql,Map<Integer,String> parameter) {
             mappedStatement.configuration = configuration;
             mappedStatement.id = id;
             mappedStatement.sqlCommandType = sqlCommandType;
             mappedStatement.parameterType = parameterType;
             mappedStatement.resultType = resultType;
             mappedStatement.sql = sql;
             mappedStatement.parameter = parameter;
         }
 ​
         public MappedStatement build() {
             assert mappedStatement.configuration != null;
             assert mappedStatement.id != null;
             return mappedStatement;
         }
     }
 }

在其中MappedStatement类是具体产品角色,内部类 Builder 担任具体建造者角色,没有明确定义一个独立的指挥者类。客户端代码在使用时直接与Builder交互,实质上承担了一部分指挥者的角色,决定何时调用Builder的构造方法及build方法来创建MappedStatement对象。

总结来说,这个实现通过内部类Builder简化了MappedStatement对象的创建过程,减少了构造函数中大量的参数带来的复杂度,体现了建造者模式的基本理念,尽管没有完全按照经典模式分离出抽象建造者和指挥者角色。客户端代码直接操作Builder来进行构建,既发挥了建造者模式的优势,又保持了代码的简洁性。

IMG_0752

在技术的星河中遨游,我们互为引路星辰,共同追逐成长的光芒。愿本文的洞见能触动您的思绪,若有所共鸣,请以点赞之手,轻抚赞同的弦。

原文地址: https://www.emanjusaka.top/2024/06/design-pattern-builder-pattern

微信公众号:emanjusaka的编程栈