假设要组装一辆自行车,并且自行车就是车轮和车架组成。
Builder对应于组装自行车所使用的车轮和车架
ConcreteBuiler对应于自行车的车轮和车架,同时可以返回一辆自行车。
Product对应于自行车。
Director表示组装过程。
此时我们再来理解下面这句话:“在软件系统中,有时候面临着“一个复杂对象”的创建工作,其通常由各个部分的子对象用一定的算法构成;由于需求的变化,这个复杂对象的各个部分经常面临着剧烈的变化,但是将它们组合在一起的算法确相对稳定。”
自行车就是“一个复杂对象”,它有车轮和车架组成,但不管车轮和车架这两个部件怎么变化,生产一辆自行车的过程是不会变的,即组装过程是不会变的。
下面是java示例代码:
/** * A bike as a concrete product we got finally * */ public class Bike { //自行车车架数量 int frameNumber; //自行车轮子数量 int wheelNumber; public Bike(){ frameNumber = 1; wheelNumber = 4; } public int getFrameNumber() { return frameNumber; } public int getWheelNumber() { return wheelNumber; } }
/** * * An abstract Builder */ public abstract class BikeBuilder { //构建bike的框架 public abstract void BuildFrame(int frameNumber); //构建bike的轮子 public abstract void BuildWheels(int wheelNumber); //获取构建好的完整的产品 public abstract Bike getBike(); }
/** * *构建自行车的各个部件 */ public class ConcreteBikeBuilder extends BikeBuilder { Bike bike; public ConcreteBikeBuilder(){ bike = new Bike(); } @Override public void BuildFrame(int frameNumber) { bike.frameNumber = frameNumber; } @Override public void BuildWheels(int wheelNumber) { bike.wheelNumber = wheelNumber; } @Override public Bike getBike() { return bike; } }
/** * *组装自行车 */ public class BikeDirector { public void createBike(BikeBuilder concreteBuilder){ concreteBuilder.BuildFrame(1); concreteBuilder.BuildWheels(4); } }
public class TestClient { public static void main(String[] args) { Bike bike = new Bike(); BikeBuilder builder = new ConcreteBikeBuilder(); BikeDirector director = new BikeDirector(); director.createBike(builder); bike = builder.getBike(); System.out.println("车架frame:" + bike.getFrameNumber()+"个"); System.out.println("轮子wheel:" + bike.getWheelNumber()+"个"); } }
测试结果:
车架frame:1个 轮子wheel:4个
四、优点和缺点
优点如下:
1、将一个复杂对象的创建过程封装起来。
2、解耦了组装过程和创建具体部件,使得我们不用去关心每个部件是如何组装的。--上面对自行车的分析可以很清楚的看出这点。
3、向客户隐藏产品内部的表现。
4、产品的实现可以被替换,因为客户只看到一个抽象的接口。
缺点如下:
1、经常被用来创建组合结构。
五、适用性
1、需要生成的产品对象有复杂的内部结构。 2、需要生成的产品对象的属性相互依赖,建造者模式可以强迫生成顺序。 3、在对象创建过程中会使用到系统中的一些其它对象,这些对象在产品对象的创建过程中不易得到。
六、实现要点
1、建造者模式主要用于“分步骤构建一个复杂的对象”,在这其中“分步骤”是一个稳定的算法,而复杂对象的各个部分则经常变化。
2、产品不需要抽象类,特别是由于创建对象的算法复杂而导致使用此模式的情况下或者此模式应用于产品的生成过程,其最终结果可能差异很大,不大可能提炼出一个抽象产品类。 3、创建者中的创建子部件的接口方法不是抽象方法而是空方法,不进行任何操作,具体的创建者只需要覆盖需要的方法就可以,但是这也不是绝对的,特别是类似文本转换这种情况下,缺省的方法将输入原封不动的输出是合理的缺省操作。
4、前面我们说过的抽象工厂模式(AbtractFactory)解决“系列对象”的需求变化,Builder模式解决“对象部分”的需求变化,建造者模式常和组合模式(Composite Pattern)结合使用。