创建型模式之建造者模式
1. 简介
建造者模式(Builder Pattern)又叫做生成器模式。他可以将复杂对象的建造过程抽象出来,使这个抽象过程的不同实现方法可以构建出不同表现的对象。
简单来说,建造者模式是将对象属性的赋值操作分离出来,通过一系列的操作对对象的属性进行赋值, 不同的操作导致对象的属性不同,也就可以构建出不同表现的对象。
注意,不是说一个操作对应一个赋值操作,两者之间没有数量关系。
2. 建造者模式的四个角色
Product
- 最终需要生成的产品对象类。Builder
- 抽象建造者,将对象的构建过程抽象成各个方法的抽象类或者接口。ConcreteBuilder
- 具体的构建者,抽象建造者具体的实现类,定义了对象构建的详细过程。Director
- 指挥者,与建造者进行组合或者聚合,客户端只与该类进行交互,就可以构建出指定的对象。
3. 代码演示
场景描述:
代码示例中我们将房子的构建过程分解成打地基、筑墙、修房顶三个步骤,分别对应房子的地基高度,墙体高度和房顶高度。
不同的具体的构建者可以构建不同的房屋结构。
package com.inconspicuousy.pattern.builder;
import lombok.AllArgsConstructor;
import lombok.Getter;
import lombok.Setter;
/**
* 产品类, 房子
* 房子由: 地基, 墙高, 屋顶高组成
* @author peng.yi
*/
@Getter
@Setter
class House {
private int base;
private int wall;
private int roof;
}
// 房子抽象建造者
abstract class HouseBuilder {
protected House house = new House();
// 打地基
public abstract void buildBasic(int basic);
// 建造房子墙
public abstract void buildWall(int wall);
// 建造房顶
public abstract void buildRoof(int roof);
// 返回最后的构建对象对象
public House builder() {
return house;
}
}
// 具体的普通房子建造器
class CommonHouseBuilder extends HouseBuilder{
@Override
public void buildBasic(int basic) {
System.out.println("普通房子打地基");
System.out.println("basic = " + basic);
house.setBase(basic);
}
@Override
public void buildWall(int wall) {
System.out.println("普通房子打墙");
System.out.println("wall = " + wall);
house.setWall(wall);
}
@Override
public void buildRoof(int roof) {
System.out.println("普通房子建房顶");
System.out.println("roof = " + roof);
house.setRoof(roof);
}
}
// 指挥者, 直接与客户交互的类
@Setter
@Getter
// 提供有参构造器
@AllArgsConstructor
class Director {
private HouseBuilder houseBuilder;
private int base;
private int wall;
private int roof;
// 通过constructHouse方法产生对应的对象
public House constructHouse() {
houseBuilder.buildBasic(base);
houseBuilder.buildWall(wall);
houseBuilder.buildRoof(roof);
return houseBuilder.builder();
}
}
public class BuilderTest {
public static void main(String[] args) {
// 获取到具体的建造器
HouseBuilder commonHouseBuilder = new CommonHouseBuilder();
// 通过指挥者构建具体的房屋
Director director = new Director(commonHouseBuilder, 5, 12, 2);
House house = director.constructHouse();
System.out.println(house);
}
}
执行结果
普通房子打地基
basic = 5
普通房子打墙
wall = 12
普通房子建房顶
roof = 2
com.inconspicuousy.pattern.builder.House@677327b6
Process finished with exit code 0
4. 优点
封装性
- 对于客户端来说不用知道产品的构建细节,通过不同的构建者就可以获取到不同表现形式的对象。扩展性强
- 通过定义不同的具体的构建者实现类,可以获取到不同表现形式的对象,符合开闭原则。
5. 抽象工厂模式与建造者模式的对比
5.1 相同点
- 都是创建型模式,用于对象的创建,封装性好,扩展性强。
5.2 不同点
- 构建的目标不一样。
抽象工厂模式:构建的目标为实现对产品家族的创建,一个产品家族是这样的一系列产品。
建造者模式:构建的目标是一个产品,只是将产品的构建过程抽象出来进行步骤式构建。