元月's blog 元月's blog
首页
  • 基础
  • 并发编程
  • JVM
  • Spring
  • Redis篇
  • Nginx篇
  • Kafka篇
  • Otter篇
  • Shardingsphere篇
  • 设计模式
  • MySQL
  • Oracle
  • 基础
  • 操作系统
  • 网络
  • 数据结构
  • 技术文档
  • Git常用命令
  • GitHub技巧
  • 博客搭建
  • 开发工具
更多

元月

临渊羡鱼,不如退而结网
首页
  • 基础
  • 并发编程
  • JVM
  • Spring
  • Redis篇
  • Nginx篇
  • Kafka篇
  • Otter篇
  • Shardingsphere篇
  • 设计模式
  • MySQL
  • Oracle
  • 基础
  • 操作系统
  • 网络
  • 数据结构
  • 技术文档
  • Git常用命令
  • GitHub技巧
  • 博客搭建
  • 开发工具
更多
  • 设计模式

    • 设计模式简介
    • 设计模式之单例模式
    • 设计模式之工厂模式
    • 设计模式之原型模式
    • 设计模式之建造者模式
      • 一、简介
      • 二、实现方式
        • 1、传统Builder模式
        • 2、简化Builder模式
      • 三、应用场景
        • 1、StringBuilder中的建造者模式:StringBuilder和StringBuffer
        • 2、MyBatis中的建造者模式:SqlSessionFactoryBuilder
      • 四、思维导图
    • 设计模式之适配器模式
    • 设计模式之桥接模式
    • 设计模式之组合模式
    • 设计模式之装饰器模式
    • 设计模式之外观模式
    • 设计模式之享元模式
    • 设计模式之代理模式
    • 设计模式之责任链模式
    • 设计模式之命令模式
    • 设计模式之解释器模式
    • 设计模式之迭代器模式
    • 设计模式之中介者模式
    • 设计模式之备忘录模式
    • 设计模式之观察者模式
    • 设计模式之状态模式
    • 设计模式之策略模式
    • 设计模式之模版模式
    • 设计模式之访问者模式
    • 设计模式辨析篇
  • 高可用

  • 系统设计
  • 设计模式
元月
2022-08-09
目录

设计模式之建造者模式

# 设计模式之建造者模式

# 一、简介

使用多个简单的对象一步一步构建成一个复杂的对象。

一些基本部件不会变,而其组合经常变化的时候,可以考虑使用建造者模式。

# 二、实现方式

# 1、传统Builder模式

传统的建造者模式包含四个角色:

  • Product(产品) 一个具体的产品对象

  • Builder(抽象建造者) 一个创建Product对象的各个部件的接口/抽象类

  • ConcreteBuilder(具体建造者) 实现了Builder接口,具体创建对象的各个部件

  • Director(指挥者) 使用Builder接口的对象。有两个作用:

    1、对客户端隐藏产品对象的创建过程

    2、控制产品对象的创建过程

具体实现

  1. 目标产品Computer类

    public class Computer {
        private String cpu;//必须
        private String ram;//必须
        private int usbCount;//可选
        private String keyboard;//可选
        private String display;//可选
    
        public Computer(String cpu, String ram) {
            this.cpu = cpu;
            this.ram = ram;
        }
        public void setUsbCount(int usbCount) {
            this.usbCount = usbCount;
        }
        public void setKeyboard(String keyboard) {
            this.keyboard = keyboard;
        }
        public void setDisplay(String display) {
            this.display = display;
        }
        @Override
        public String toString() {
            return "Computer{" +
                    "cpu='" + cpu + '\'' +
                    ", ram='" + ram + '\'' +
                    ", usbCount=" + usbCount +
                    ", keyboard='" + keyboard + '\'' +
                    ", display='" + display + '\'' +
                    '}';
        }
    }
    
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
  2. 抽象建造者类

    public abstract class ComputerBuilder {
        public abstract void setUsbCount();
        public abstract void setKeyboard();
        public abstract void setDisplay();
    
        public abstract Computer build();
    }
    
    1
    2
    3
    4
    5
    6
    7
  3. 具体建造者类

    public class MacComputerBuilder extends ComputerBuilder {
        private Computer computer = new Computer();
    
        @Override
        public void setUsbCount() {
            computer.setUsbCount(2);
        }
        @Override
        public void setKeyboard() {
            computer.setKeyboard("苹果键盘");
        }
        @Override
        public void setDisplay() {
            computer.setDisplay("苹果显示器");
        }
        @Override
        public Computer build() {
            return computer;
        }
    }
    
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
  4. 指导者类(Director)

    public class ComputerDirector {
        public void makeComputer(ComputerBuilder builder){
            builder.setUsbCount();
            builder.setDisplay();
            builder.setKeyboard();
        }
    }
    
    1
    2
    3
    4
    5
    6
    7
  5. 测试类

    public static void main(String[] args) {
            ComputerDirector director=new ComputerDirector();//1
            ComputerBuilder builder=new MacComputerBuilder("I5处理器","三星125");//2
            director.makeComputer(builder);//3
            Computer macComputer=builder.build();//4
            System.out.println("mac computer:"+macComputer.toString());
    }
    
    1
    2
    3
    4
    5
    6
    7

# 2、简化Builder模式

传统的builder模式存在许多变种,其中一种省略了director 这个角色,将构建算法交给了client端,其次将builder 写到了要构建的产品类里面,最后采用了链式调用

代码实现如下:

public class Computer {
    private final String cpu;//必须
    private final String ram;//必须
    private final int usbCount;//可选
    private final String keyboard;//可选
    private final String display;//可选
    private Computer(Builder builder){
        this.cpu=builder.cpu;
        this.ram=builder.ram;
        this.usbCount=builder.usbCount;
        this.keyboard=builder.keyboard;
        this.display=builder.display;
    }
    public static class Builder{
        private String cpu;//必须
        private String ram;//必须
        private int usbCount;//可选
        private String keyboard;//可选
        private String display;//可选
        public Builder(String cup,String ram){
            this.cpu=cup;
            this.ram=ram;
        }
        public Builder setUsbCount(int usbCount) {
            this.usbCount = usbCount;
            return this;
        }
        public Builder setKeyboard(String keyboard) {
            this.keyboard = keyboard;
            return this;
        }
        public Builder setDisplay(String display) {
            this.display = display;
            return this;
        }
        public Computer build(){
            return new Computer(this);
        }
    }
    //省略getter方法
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41

测试代码:

Computer computer=new Computer.Builder("因特尔","三星")
                .setDisplay("三星24寸")
                .setKeyboard("罗技")
                .setUsbCount(2)
                .build();
1
2
3
4
5

# 三、应用场景

# 1、StringBuilder中的建造者模式:StringBuilder和StringBuffer

我们先看一下这两个类的结构图:

其中Appendable接口定义了几种append方法,因此,它是一个抽象建造者

AbstractStringBuilder虽然是一个抽象类,但是它实现了Appendable接口,并重写了append方法。因此,它是一个具体建造者

StringBuilder和StringBuffer继承了AbstractStringBuilder,它们通过调用父类AbstractStringBuilder的append方法的形式重写了append方法。因而,它们是具体建造者,同时又充当了指挥者(Director)的角色

@Override
    public StringBuilder append(String str) {
        super.append(str);
        return this;
    }
1
2
3
4
5

# 2、MyBatis中的建造者模式:SqlSessionFactoryBuilder

SqlSessionFactory是通过SqlSessionFactoryBuilder创建的,代码如下:

public SqlSessionFactory build(Configuration config) {
        return new DefaultSqlSessionFactory(config);
  }
1
2
3

SqlSessionFactory的创建需要Configuration,Configuration的属性非常多,创建起来非常繁杂,便通过XMLConfigBuilder的parse()方法构建Configuration实例

XMLConfigBuilder负责创建 Configuration的各个部件,如下图所示。

private void parseConfiguration(XNode root) {
        try {
            this.propertiesElement(root.evalNode("properties"));
            Properties settings = this.settingsAsProperties(root.evalNode("settings"));
            this.loadCustomVfs(settings);
            this.typeAliasesElement(root.evalNode("typeAliases"));
            this.pluginElement(root.evalNode("plugins"));
            this.objectFactoryElement(root.evalNode("objectFactory"));
            this.objectWrapperFactoryElement(root.evalNode("objectWrapperFactory"));
            this.reflectorFactoryElement(root.evalNode("reflectorFactory"));
            this.settingsElement(settings);
            this.environmentsElement(root.evalNode("environments"));
            this.databaseIdProviderElement(root.evalNode("databaseIdProvider"));
            this.typeHandlerElement(root.evalNode("typeHandlers"));
            this.mapperElement(root.evalNode("mappers"));
        } catch (Exception var3) {
            throw new BuilderException("Error parsing SQL Mapper Configuration. Cause: " + var3, var3);
        }
    }
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19

在上面的例子中:

Configuration相当于产品。

XMLConfigBuilder负责创建复杂对象Configuration,相当于具体建造者。

XMLConfigBuilder 继承自 BaseBuilder,所以BaseBuilder相当于是抽象建造者。

SqlSessionFactoryBuilder调用XMLConfigBuilder中构造对象的方法,相当于指挥者。

# 四、思维导图

#设计模式
设计模式之原型模式
设计模式之适配器模式

← 设计模式之原型模式 设计模式之适配器模式→

最近更新
01
otter二次开发-支持按目标端主键索引Load数据
08-03
02
mvnw简介
06-21
03
gor流量复制工具
06-03
更多文章>
Theme by Vdoing | Copyright © 2022-2024 元月 | 粤ICP备2022071877号-1
  • 跟随系统
  • 浅色模式
  • 深色模式
  • 阅读模式