建造者模式

简介: 主要内容有:该设计模式的详细介绍,包括:引子,意图(大白话解释)类图,时序图(理论规范)该模式的代码示例:熟悉它长的样子该模式的实际使用案例:了解它在哪些重要的源码中出现过


前言



主要内容有:

  • 该设计模式的详细介绍,包括:
  • 引子,意图(大白话解释)
  • 类图,时序图(理论规范)
  • 该模式的代码示例:熟悉它长的样子
  • 该模式的实际使用案例:了解它在哪些重要的源码中出现过


创建型:建造者模式 Builder



引子

根据中文翻译的不同,建造者模式又可以称为生成器模式,它属于创建型模式。

复杂对象相当于一辆有待建造的汽车,而对象的属性相当于汽车的部件,建造产品的过程就相当于组合部件的过程。由于组合部件的过程很复杂,因此,这些部件的组合过程往往被“外部化”到一个称作建造者的对象里,建造者返还给客户端的是一个已经建造完毕的完整产品对象,而用户无须关心该对象所包含的属性以及它们的组装方式,这就是建造者模式的模式动机。

我们常用的StringBuilder就是一个建造者模式的典型例子


意图

建造者模式(Builder Pattern):将一个复杂对象的构建与它的表示分离,使得同样的构建过程可以创建不同的表示。


类图

如果看不懂UML类图,可以先粗略浏览下该图,想深入了解的话,可以继续谷歌,深入学习:

建造者模式包含如下角色:

  • Builder:抽象建造者 (我们经常会看到AbstractXXXX类)
  • ConcreteBuilder:具体建造者
  • Director:指挥者
  • Product:产品角色

下图是建造者模式得到UML图,可以看到:

  • ConcreteBuilder是Builder的实现关系
  • Builder聚合到Director上,因为Director还可以干别的事情


时序图

时序图(Sequence Diagram)是显示对象之间交互的图,这些对象是按时间顺序排列的。时序图中显示的是参与交互的对象及其对象之间消息交互的顺序。

我们可以大致浏览下时序图,如果感兴趣的小伙伴可以去深究一下:


实现


1. 建造一个水杯

一水杯工厂要生产各式各样的水杯,无论杯子是神马造型,但都包括绳子,帽子和杯体。以此模型创建各种类型的杯子。

cup-->Product类

public class Cup {
    private String string;    //绳子
    private String cap;       //帽子
    private String cupBody;   //杯体
    public void setString(String string) {
        this.string = string;
    }
    public void setCap(String cap) {
        this.cap = cap;
    }
    public void setCupBody(String cupBody) {
        this.cupBody = cupBody;
    }
    public void show() {
        System.out.println("杯子生产完毕");
    }
}
复制代码

Builder-->Builder类

public abstract class  Builder {
    protected Cup cup = new Cup();
    public abstract void buildString();
    public abstract void buildCap();
    public abstract void buildCupBody();
    public  Cup getResult() {
        return cup;
    }
}
复制代码

ClassCup-->concrateBuilder类

public class ClassCup extends Builder {
    @Override
    public void buildString() {
        cup.setString("生产绳子...");
        System.out.println("生产绳子...");
    }
    @Override
    public void buildCap() {
        cup.setCap("生产帽子...");
        System.out.println("生产帽子...");
    }
    @Override
    public void buildCupBody() {
        cup.setCupBody("生产杯体...");
        System.out.println("生产杯体...");
    }
}
复制代码

Director类

public class Director {
    private Builder builder;
    public Director(Builder builder) {
        this.builder = builder;
    }
    public void create() {
        builder.buildString();
        builder.buildCap();
        builder.buildCupBody();
        builder.getResult().show();
    }
    public static void main(String[] args) {
        Director d = new Director(new ClassCup());
        d.create();
    }
}
复制代码


2. 编写一个简易的java.lang.StringBuilder

AbstractStringBuilder-->Builder类

public class AbstractStringBuilder {
    protected char[] value;
    protected int count;
    public AbstractStringBuilder(int capacity) {
        count = 0;
        value = new char[capacity];
    }
    public AbstractStringBuilder append(char c) {
        ensureCapacityInternal(count + 1);
        value[count++] = c;
        return this;
    }
    private void ensureCapacityInternal(int minimumCapacity) {
        // overflow-conscious code
        if (minimumCapacity - value.length > 0)
            expandCapacity(minimumCapacity);
    }
    void expandCapacity(int minimumCapacity) {
        int newCapacity = value.length * 2 + 2;
        if (newCapacity - minimumCapacity < 0)
            newCapacity = minimumCapacity;
        if (newCapacity < 0) {
            if (minimumCapacity < 0) // overflow
                throw new OutOfMemoryError();
            newCapacity = Integer.MAX_VALUE;
        }
        value = Arrays.copyOf(value, newCapacity);
    }
}
复制代码

StringBuilder-->concrateBuilder类

public class StringBuilder extends AbstractStringBuilder {
    public StringBuilder() {
        super(16);
    }
    @Override
    public String toString() {
        // Create a copy, don't share the array
        return new String(value, 0, count);
    }
}
复制代码

Client-->Director类

public class Client {
    public static void main(String[] args) {
        StringBuilder sb = new StringBuilder();
        final int count = 26;
        for (int i = 0; i < count; i++) {
            sb.append((char) ('a' + i));
        }
        System.out.println(sb.toString());
    }
}
复制代码


优缺点


优点

  • 在建造者模式中, 客户端不必知道产品内部组成的细节,将产品本身与产品的创建过程解耦,使得相同的创建过程可以创建不同的产品对象。
  • 每一个具体建造者都相对独立,而与其他的具体建造者无关,因此可以很方便地替换具体建造者或增加新的具体建造者, 用户使用不同的具体建造者即可得到不同的产品对象 。
  • 可以更加精细地控制产品的创建过程。将复杂产品的创建步骤分解在不同的方法中,使得创建过程更加清晰,也更方便使用程序来控制创建过程。
  • 增加新的具体建造者无须修改原有类库的代码,指挥者类针对抽象建造者类编程,系统扩展方便,符合“开闭原则”。


缺点

  • 建造者模式所创建的产品一般具有较多的共同点,其组成部分相似,如果产品之间的差异性很大,则不适合使用建造者模式,因此其使用范围受到一定的限制。
  • 如果产品的内部变化复杂,可能会导致需要定义很多具体建造者类来实现这种变化,导致系统变得很庞大。


使用场景举例



JDK中使用


参考



blog.csdn.net/c275046758/…

github.com/CyC2018/CS-…

design-patterns.readthedocs.io/zh_CN/lates…

相关文章
|
3月前
|
设计模式 Java 机器人
Java设计模式-建造者模式
建造者(Builder)模式指将一个产品的内部表象与产品的生成过程分割开来,从而可以使一个建造过程生成具有不同的内部表象的产品对象。它是把对象的构建和表述分离。
44 0
Java设计模式-建造者模式
|
5月前
|
设计模式 Java Maven
【建造者模式】
【建造者模式】
|
1月前
|
设计模式 C++
【C++】—— 建造者模式
【C++】—— 建造者模式
|
7月前
|
算法 程序员
建造者模式的运用
建造者模式的运用
27 0
|
4月前
创建型 建造者模式
创建型 建造者模式
24 0
|
4月前
|
Java Linux Spring
终于懂了建造者模式
终于懂了建造者模式
17 1
|
5月前
建造者模式
建造者模式
25 1
|
8月前
|
设计模式 C++
2023-6-13-第四式建造者模式
2023-6-13-第四式建造者模式
46 0
|
9月前
|
缓存 Java C++
建造者模式解读
建造者模式解读
建造者模式解读
|
11月前
|
算法
创建型模式-建造者模式
创建型模式-建造者模式
43 0