建造者模式(Builder Pattern)是对象的创建模式。建造者模式可以将一个产品的内部表象(internal representation)与产品的生产过程分割开来,从而可以使一个建造过程生成具有不同的内部表象的产品对象。
概念
将一个复杂对象的构建与其表象分离,使得同样的构建过程可以创建不同的表示。
- 适用场景:
- 构建的对象具有复杂的内部结构。
- 对象的构建过程需要多个步骤,并且这些步骤可能变化。
- 希望解耦构建过程与具体实现。
模式结构
建造者模式通常包含以下角色:
- Product: 要构建的复杂对象
- Builder: 定义构建产品的各个步骤的接口(如
buildPartA()
,buildPartB()
等),也可以是一个抽象类或接口。
- ConcreteBuilder: 实现Builder接口,具体完成各部分的构建,并提供一个获取产品的方法。
- Director: 负责调用构建者中的步骤来构建产品,不关心具体实现,只控制流程。
- Client: 最终客户端。
示例代码:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68
| class House { private String foundation; private String walls; private String roof; public void setFoundation(String foundation) { this.foundation = foundation; } public void setWalls(String walls) { this.walls = walls; } public void setRoof(String roof) { this.roof = roof; } public void show() { System.out.println("Foundation: " + foundation); System.out.println("Walls: " + walls); System.out.println("Roof: " + roof); } }
interface HouseBuilder { void buildFoundation(); void buildWalls(); void buildRoof(); House getHouse(); }
class ConcreteHouseBuilder implements HouseBuilder { private House house = new House(); public void buildFoundation() { house.setFoundation("Built with bricks"); } public void buildWalls() { house.setWalls("Reinforced concrete walls"); } public void buildRoof() { house.setRoof("Tile roof"); } public House getHouse() { return house; } }
class HouseDirector { private HouseBuilder builder; public HouseDirector(HouseBuilder builder) { this.builder = builder; } public void constructHouse() { builder.buildFoundation(); builder.buildWalls(); builder.buildRoof(); } }
public class Client { public static void main(String[] args) { HouseBuilder builder = new ConcreteHouseBuilder(); HouseDirector director = new HouseDirector(builder); director.constructHouse(); House house = builder.getHouse(); house.show(); } }
|
优点: 分离构建逻辑和表示;多样化输出;控制构建过程
缺点: 不适合简单对象,如果对象构造过程简单,使用该模式反而增加复杂度;需要定义多个类,增加了系统的类数量,增加了理解成本。
场景举例
- 构建不同配置的计算机(cpu、内存、硬盘等)
- 生成不同风格的文档(PDF、HTML、Word)
- 组装汽车的不同型号(发动机、轮子、颜色等)
- 游戏中的角色的定制(武器、服装、技能等)
和Lombok插件的区别
- Lombok的
@Builder
并不完全等同于GoF的建造者模式。
- 它缺少
Director
角色,也不支持多个ConcreteBuilder
实现。
- 如需要对构建过程作复杂的控制(如分布构建、条件判断、模板化流程),仍需要手动实现建造者模式。
- Lombok的
@Builder
只对简单对象的私有属性进行构建。