核心思想
- 生成器模式(Builder Pattern)是一种创建型设计模式,用于分步骤构建复杂对象,允许用户通过控制对象构造的过程,定制对象的组成部分,而无需直接实例化它们的细节。建造者模式特别适合构建具有多种配置的复杂对象。
结构
1. Builder(抽象建造者)
- 定义构造产品的抽象方法,具体建造者将实现这些方法。
2. ConcretBuilder(具体建造者)
- 实现
Builder
接口,定义构造复杂对象的具体过程。
3. Director(指挥者)
4. Product(产品)
适用场景
- 需要创建复杂对象,且对象由多个部分组成,这些部分可能需要动态配置。
- 构造过程需要对外隐藏,但允许分步骤构造。
- 需要让对象的构造过程和表示分离,提供不同的表示形式。
优缺点
优点:
- 更好的控制:通过分步构建产品,细化构造过程。
- 代码复用:可以通过不同的具体建造者实现构建不同的产品。
- 解耦性:构造和表示分离。
缺点:
- 增加复杂性:需要额外定义建造者和指挥者类。
- 不适合简单对象:对于简单对象,可能显得过于繁琐。
实现步骤
- 定义一个实现
Cloneable
接口的原型类。 - 在类中重写
clone()
方法,确保对象的复制逻辑。 - 调用原型的
clone()
方法创建新对象。
注意事项
1. 浅拷贝与深拷贝:
- 浅拷贝:只复制对象的基本数据类型,引用类型属性仍指向原始对象。
- 深拷贝:不仅复制基本类型,也复制引用类型的对象,创建一个完全独立的副本。
2. Cloneable
接口:
- 在 Java 中,必须实现
Cloneable
接口并重写 clone()
方法,否则会抛出 CloneNotSupportedException
。
3. 不适用场景:
- 对于高度依赖构造函数或不支持
clone()
的框架。
示例
拓展——链式调用
package com.colin.patterns.creational_patterns.chain_builder;
public class Phone {
private String cpu;
private String screen;
private String memory;
private String mainboard;
// 私有构造方法
private Phone(Builder builder) {
this.cpu = builder.cpu;
this.screen = builder.screen;
this.memory = builder.memory;
this.mainboard = builder.mainboard;
}
public static final class Builder {
private String cpu;
private String screen;
private String memory;
private String mainboard;
public Builder cpu(String val) {
cpu = val;
return this;
}
public Builder screen(String val) {
screen = val;
return this;
}
public Builder memory(String val) {
memory = val;
return this;
}
public Builder mainboard(String val) {
mainboard = val;
return this;
}
// 使用Builder创建实例
public Phone build() {
return new Phone(this);
}
}
@Override
public String toString() {
return "Phone{" +
"cpu='" + cpu + '\'' +
", screen='" + screen + '\'' +
", memory='" + memory + '\'' +
", mainboard='" + mainboard + '\'' +
'}';
}
}
package com.colin.patterns.creational_patterns.chain_builder;
public class Client {
public static void main(String[] args) {
Phone phone = new Phone.Builder()
.cpu("Intel Core i7")
.memory("16GB")
.screen("13.3\"")
.mainboard("Intel HM")
.build();
System.out.println(phone);
}
}
与其他模式的关系