建造者模式:将一个复杂对象的构建与它的表示分离,使得同样的构建过程可以创建不同的表示。
通俗点讲:建造者模式类似同一条生产线,生产过程可以一样,但是放入的材料不一样生产出来的产品就不一样,比如放入纸就生产出纸碗,放入铁就生产出铁腕。又如个人电脑组装,组装步骤和顺序差不多,但是使用的显示器,显卡,内存,硬盘,操作系统都可以不一样,虽然最终都是组装出来电脑,但是配置完全不一样。
标准 Builder
模式
类图结构
结构解析
Director
指挥者,使用 Builder
接口构建一个对象。Director
隔离了客户和产品的组装过程,客户并不需要关心产品的组装。
Builder
为创建一个 Product
对象的各个部件指定的抽象接口。
ConcreteBuilder
具体的构建者,实现 Builder
接口,构建和装配各个部件或配置,生成最终的产品。
Product
具体产品。构造方法,属性设置都被设置为 default
,客户无法实例化或设置属性,只能通过 Builder
模式来构造。
Builder
模式就是设计一个流程,指定哪些步骤必须执行,抽象到接口中去,子类必须实现这些接口。Director
组装产品实现统一的组装过程;不同的 ConcreteBuilder
对应产品不同的表现形式,每个 ConcreteBuilder
会生成具体的产品。也就是说客户并不需要关心产品的组装过程和构造,只需要通过 ConcreteBuilder
获取最终的产品就行。
示例
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 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131
| public class VehicleProduct { private String type; private String engine; private String wheels; private String doors;
VehicleProduct(String type){ this.type = type; }
void setEngine(String engine){ this.engine = engine; }
void setWheels(String wheels) { this.wheels = wheels; }
void setDoors(String doors) { this.doors = doors; }
public void show(){ System.out.println(type + ".engine = " + engine); System.out.println(type + ".wheels = " + wheels); System.out.println(type + ".doors = " + doors); } }
public abstract class VehicleBuilder { public abstract void buildEngine(); public abstract void buildWheels(); public abstract void buildDoors(); public abstract VehicleProduct getProduct(); }
public class ShopDirector {
private VehicleBuilder mBuilder;
public ShopDirector(VehicleBuilder builder){ mBuilder = builder; }
public void construct(){ mBuilder.buildEngine(); mBuilder.buildWheels(); mBuilder.buildDoors(); } }
public class CarBuilder extends VehicleBuilder{ private VehicleProduct vehicle = new VehicleProduct("car");
@Override public void buildEngine() { vehicle.setEngine("oil"); }
@Override public void buildWheels() { vehicle.setWheels("four"); }
@Override public void buildDoors() { vehicle.setDoors("four"); }
@Override public VehicleProduct getProduct() { return vehicle; } }
public class MotorCycleBuilder extends VehicleBuilder{ private VehicleProduct vehicle = new VehicleProduct("motor");
@Override public void buildEngine() { vehicle.setEngine("electric"); }
@Override public void buildWheels() { vehicle.setWheels("two"); }
@Override public void buildDoors() { vehicle.setDoors("no"); }
@Override public VehicleProduct getProduct() { return vehicle; } }
public class TestStandardBuilder {
public static void main(String[] args) { CarBuilder carBuilder = new CarBuilder(); ShopDirector carDirector = new ShopDirector(carBuilder); carDirector.construct(); VehicleProduct car = carBuilder.getProduct(); car.show();
MotorCycleBuilder motorCycleBuilder = new MotorCycleBuilder(); ShopDirector motorDirector = new ShopDirector(motorCycleBuilder); motorDirector.construct(); VehicleProduct motor = motorCycleBuilder.getProduct(); motor.show(); } }
car.engine = oil car.wheels = four car.doors = four motor.engine = electric motor.wheels = two motor.doors = no
|
小结
创建一个复杂对象,这些对象的内部构建顺序通常是固定的,但是对象的内部构造通常面临复杂的变化。建造者模式的好处就是使得建造代码与表示代码分离,建造者隐藏了产品的建造过程,如果需要改变产品的内部表示,重新定义一个具体的建造者就可以了。
标准 Builder
模式,当需要构建一个不同属性的产品时,只需要继承 Builder
重新实现即可。比如需要新增一个小型摩托车产品,实现 ScooterBuilder
来创建它。标准模式的整个架构非常方便扩展,但是会增加很多类。
常用简化 Builder
模式
标准模式中扩展时会增加很多类,通常我们都会简化这个模式,只需要两个类就可以实现。Director
和抽象 Builder
两个角色通常被省略,而具体类 Builder
代表了指挥者和建造者双重角色,同时被设计为链式调用,即每个方法都返回 this
。比如:
new Product.Builder().setA().setB().build()
类图结构
结构解析
Product
具体产品。构造方法和属性设置被设置为 default
,只能通过 Builder
来构造。
Builder
Product
的内部类,用来构造 Product
, 构造前设置各种属性。
Product
的构造和属性设置都放到 Builder
中,通过 Builder.build
构造出需要的产品。
示例
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
| public class Product { private String name; private int num;
Product(String name, int num){ this.name = name; this.num = num; }
public void show(){ System.out.println("name = " + name); System.out.println("num = " + num); }
public static final class Builder{ private String name; private int num;
public Builder setName(String name) { this.name = name; return this; }
public Builder setNum(int num) { this.num = num; return this; }
public Product build(){ return new Product(name, num); } } }
public class TestSimpleBuilder { public static void main(String[] args) { Product product = new Product.Builder() .setName("Bike") .setNum(1) .build(); product.show(); } }
name = Bike num = 1
|
小结
简化型的 Builder
模式中:Builder
类非常关键,封装了产品的构建过程,产品不同的表现形式也是通过 Builder.set
来改变的。
总结
不管是标准型还是简化型,复杂对象的构建以及属性的设置都被隐藏了,使得复杂对象只能通过 Builder
模式来创建。
创建型设计模式的统一特点:对象一旦被创建,所有的行为或表示就固定下来了,所有的变化都体现在创建的过程中。
参考文档