设计模式之建造者模式
1. 概括
如果有一个要创建一个复杂的对象,可以使用建造者模式(生成器),
创建一个专门生成特定一个对象的类,把要生成的对象中每个属性的创建抽离出来
创建指挥者类,用来控制生成属性的步骤顺序
创建者模式注重对象复杂的生成【过程】
2. 结构
- 抽象生成器:定义属性的步骤(方法)
- 具体生成器:提供不同最终产品的构造过程,提供返回最终产品的方法
- 产品:生成器最终生成的对象
- 指挥者:调用生成器的步骤,构造最终产品
3. 使用场景
- 当你创建的对象过于复杂,并且过程只有一些较小的不同
4. 优缺点
- 优点
- 开闭
- 依赖倒转
- 单一职责
- 可以把对象复杂的创建过程封闭起来
- 缺点
- 要写大量的类
- 当对象之间的差异过大不适合用
5. 与工厂模式的比较
- 生成器用来创建一个复杂的对象,而工厂创建一个系列产品
- 生成器因为步骤可能不同,所以要有一个指挥者
6. 举个栗子
- 自行车的生产,每个部件可能有较复杂的生产步骤,可以用建造者,
- 产品
public class Client {
public static void main(String[] args) {
Director director = new Director(new MobileBikeBuilder());
Bike bike = director.construct();
System.out.println(bike);
}
}
- 抽象建造者
public class Bike {
private String frame;
private String seat;
/**
consturtor
getter
setter
*/
}
- 具体建造者
public class MobileBikeBuilder extends Builder{
@Override
public void createFrame() {
bike.setFrame("摩拜 车架");
}
@Override
public void createSeat() {
bike.setSeat("摩拜 车座");
}
@Override
public Bike getProduct() {
return this.bike;
}
}
public class OfoBikeBuilder extends Builder{
@Override
public void createFrame() {
bike.setFrame("ofo 车架");
}
@Override
public void createSeat() {
bike.setSeat("ofo 车座");
}
@Override
public Bike getProduct() {
return this.bike;
}
}
- 指挥者
public class Director {
private Builder builder;
public Director(Builder builder) {
this.builder = builder;
}
// 创建产品,指定建造顺序
public Bike construct() {
builder.createFrame();
builder.createSeat();
return builder.getProduct();
}
}
- 调用
public class Client {
public static void main(String[] args) {
Director director = new Director(new MobileBikeBuilder());
Bike bike = director.construct();
System.out.println(bike);
}
}
- 注意:这里只是例子,在实际的应用中,builder的属性建造方法中可能有复杂的代码,这也是我们希望这样使用的,把复杂属性的建造抽离出来
7. builder模式
public class Person {
private String name;
private String sex;
private Integer height;
public Person(Builder builder) {
this.name = builder.name;
this.sex = builder.sex;
this.height = builder.height;
}
// 建造器
public static final class Builder {
private String name;
private String sex;
private Integer height;
public Builder setName(String name) {
this.name = name;
return this;
}
public Builder setSex(String sex) {
this.sex = sex;
return this;
}
public Builder setHeight(Integer height) {
this.height = height;
return this;
}
public Person build() {
return new Person(this);
}
}
@Override
public String toString() {
return "Person{" +
"name='" + name + '\'' +
", sex='" + sex + '\'' +
", height=" + height +
'}';
}
}
public class Client {
public static void main(String[] args) {
Person person = new Person.Builder().setSex("男").setHeight(180).setName("张三").build();
System.out.println("person = " + person);
}
}
8. 对比
都是创建者类型的设计模式
- 生成器注重的是一个复杂属性对象的创建,分步生成,执行一些步骤返回产品,所以需要一个指挥者类
- 抽象工厂是生成一系列的对象产品,直接返回产品