意图
封装一个对象的构造过程,并允许按步骤构造。
类图
classDiagram
class Builder {
<<abstract>>
+buildPart()* void
+getResult() Product
}
class ConcreteBuilder {
+buildPart() void
+getResult() Product
}
class Director {
-builder Builder
+construct() Product
}
class Product
Director o-- Builder
Builder <|-- ConcreteBuilder
ConcreteBuilder ..> Product : 逐步构建
Builder:抽象生成器,声明构造产品各部件的接口ConcreteBuilder:具体生成器,实现各部件的构造与装配,提供获取最终产品的方法Director:指挥者,安排部件的构造顺序(哪些步骤、什么顺序),对客户端屏蔽构造细节Product:被逐步构造的复杂对象
实现
以下是一个简易的 StringBuilder 实现,参考 JDK 1.8 源码:
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);
}
}
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);
}
}
客户端使用:
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());
}
}
输出:
abcdefghijklmnopqrstuvwxyz
JDK 中的应用
java.lang.StringBuilderjava.lang.StringBufferjava.nio.ByteBuffer(ByteBuffer.allocate(48).put(...)按步骤构建)java.lang.Appendable- Apache Camel builders
- Lombok 的
@Builder(编译期生成链式构造代码,见开发工具系列:Lombok)
总结
读完之后问自己下面几个问题,直到可以流利地回答:
- 使用的场景?
- 本质是什么?
- 它解决了什么问题?
- 它体现了设计模式中什么原则?
- 存在的缺陷?
- 你认为与它相关的设计模式有哪些?它们之间的区别有哪些?
- 开源架构中哪些使用了这一模式?