第0章:简介
生成器模式定义:将一个复杂对象的构建与它的表示分离,使得同样地构建过程可以创建不同的表示。
生成器模式的实质:分离整体构建算法和部件构建
参考:http://chjavach.iteye.com/blog/1617078,研磨设计模式(书籍),大话设计模式(书籍)
模式图:
待补充
第1章:实践
第0节:简单生成器模式
(1)生成器接口(Builder.java)
package com.mcc.core.designPattern.build.builder.simpleBuilder; /** * 生成器接口,这里是对象的构建表示,这里不要求构建过程 * * 生成器模式的定义:将一个复杂对象的构建与它的表示分离,使得同样地构建过程可以创建不同的表示。 * 生成器模式的表示:分离整体构建算法和部件构建 * * @author menergy * DateTime: 14-3-9 下午12:54 */ public interface Builder { //构建步骤1 public void buildStep1(); //构建步骤2 public void buildStep2(); //构建步骤3 public void buildStep3(); } |
(2)生成器A类(BuilderImplA.java)
package com.mcc.core.designPattern.build.builder.simpleBuilder; /** * 生成器A * * @author menergy * DateTime: 14-3-9 下午1:01 */ public class BuilderImplA implements Builder { @Override public void buildStep1() { System.out.println("生成器A构建步骤1"); } @Override public void buildStep2() { System.out.println("生成器A构建步骤2"); } @Override public void buildStep3() { System.out.println("生成器A构建步骤3"); } } |
(3)生成器B类(BuilderImplB.java)
package com.mcc.core.designPattern.build.builder.simpleBuilder; /** * 生成器B * * @author menergy * DateTime: 14-3-9 下午1:03 */ public class BuilderImplB implements Builder { @Override public void buildStep1() { System.out.println("生成器B构建步骤1"); } @Override public void buildStep2() { System.out.println("生成器B构建步骤2"); } @Override public void buildStep3() { System.out.println("生成器B构建步骤3"); } } |
(4)指导器类(Director.java)
package com.mcc.core.designPattern.build.builder.simpleBuilder; /** * 指导器,指导使用生成器的接口来生成目标产品 * * @author menergy * DateTime: 14-3-9 下午1:06 */ public class Director { //当前需要使用的生成器对象 private Builder builder; /** * 构造方法,传入生成器 * @param builder */ public Director(Builder builder){ this.builder = builder; } /** * 指导生成器构建产品,这里控制构建流程 */ public void build(){ //构建步骤1 builder.buildStep1(); //构建步骤2 builder.buildStep2(); //构建步骤3 builder.buildStep3(); } } |
第1节:复杂生成器模式(不带约束条件)
(1)复杂对象生成器类(ComplexBuilder.java)
package com.mcc.core.designPattern.build.builder.unconstraintBuilder; /** * 复杂对象生成器,不对属性加约束条件 * * @author menergy * DateTime: 14-3-9 下午4:08 */ public class ComplexBuilder { //必须初始属性 private String property1; private String property2; //非必须初始属性 private String property3; private String property4; /** * 构造器,传入必须初始属性 * @param property1 * @param property2 */ public ComplexBuilder(String property1,String property2){ this.property1 = property1; this.property2 = property2; } /** * 设置property3属性值 * @param property3 * @return */ public ComplexBuilder setProperty3(String property3){ this.property3 = property3; return this; } /** * 设置property4属性值 * @param property4 * @return */ public ComplexBuilder setProperty4(String property4){ this.property4 = property4; return this; } /** * 创建真正的对象并返回 * @return */ public ComplexObject build(){ return new ComplexObject(this); } //提供getter方法供外部访问,不提供setter方法 public String getProperty1() { return property1; } public String getProperty2() { return property2; } public String getProperty3() { return property3; } public String getProperty4() { return property4; } } |
(2)复杂对象类(ComplexObject.java)
package com.mcc.core.designPattern.build.builder.unconstraintBuilder; /** * 复杂对象 * * @author menergy * DateTime: 14-3-9 下午4:00 */ public class ComplexObject { private String property1; private String property2; private String property3; private String property4; /** * 构造器,访问级别是同包能访问 * @param builder */ ComplexObject(ComplexBuilder builder){ this.property1 = builder.getProperty1(); this.property2 = builder.getProperty2(); this.property3 = builder.getProperty3(); this.property4 = builder.getProperty4(); } /** * 其它操作 */ public void someMethod(){ System.out.println("调用复杂对象的操作方法"); } } |
(3)客户端测试类(Client.java)
package com.mcc.core.designPattern.build.builder.unconstraintBuilder; /** * 客户端测试 * * @author menergy * DateTime: 14-3-9 下午4:23 */ public class Client { public static void main(String args[]){ //创建生成器 ComplexBuilder builder = new ComplexBuilder("value1","value2"); //生成对象,拼接方式设置非必须属性的值 ComplexObject complexObject = builder.setProperty3("value3").setProperty4("value4").build(); //调用对象其它操作 complexObject.someMethod(); } |
第2节:复杂生成器模式(带约束条件)
(1)复杂对象(含构建)类(ComplexObject.java)
package com.mcc.core.designPattern.build.builder.constraintBuilder; /** * 复杂对象,融入构建方式,对属性过滤 * * @author menergy * DateTime: 14-3-9 下午4:33 */ public class ComplexObject { private String property1; private String property2; private String property3; private String property4; /** * 构造器,访问级别私有 * @param builder */ private ComplexObject(ComplexBuilder builder){ } /** * 其它操作 */ public void someMethod(){ System.out.println("调用复杂对象的操作方法"); } /** * 类级内部类,构建对象 */ public static class ComplexBuilder{ private String property1; private String property2; private String property3; private String property4; /** * 构造器,传入必须初始属性 * @param property1 * @param property2 */ public ComplexBuilder(String property1,String property2){ this.property1 = property1; this.property2 = property2; } /** * 设置property3属性值 * @param property3 * @return */ public ComplexBuilder setProperty3(String property3){ this.property3 = property3; return this; } /** * 设置property4属性值 * @param property4 * @return */ public ComplexBuilder setProperty4(String property4){ this.property4 = property4; return this; } /** * 创建真正的对象并返回 * @return */ public ComplexObject build(){ //这里是构建前对属性的过滤逻辑,这里不做过滤 //返回构建的复杂对象 return new ComplexObject(this); } } } |
(2)客户端测试类(Client.java)
package com.mcc.core.designPattern.build.builder.constraintBuilder; /** * 客户端测试类 * * @author menergy * DateTime: 14-3-9 下午4:42 */ public class Client { public static void main(String args[]){ //创建构建器 ComplexObject.ComplexBuilder builder = new ComplexObject.ComplexBuilder("value1","value2"); //构建对象 ComplexObject complexObject = builder.setProperty3("value3").setProperty4("value4").build(); //调用复杂对象方法 complexObject.someMethod(); } } |
思考:
Builder模式主要是为了将构建复杂对象的过程和它的部件解耦。使得我们不用去关心每个部件是如何组装的。
当我们需要生成一个相对复杂的对象,这个复杂的对象生成过程的内部属性有一定的顺序逻辑或者某种组合逻辑,但对于客户端(使用者)来说,不需要关注生成的细节和顺序,只要可以提供构建好的对象就可以, 或者业务上需要对客户端屏蔽这种细节和顺序,这时我们可以使用生成器模式(建造者模式)来生成这个相对复杂的对象给客户端,具体细节和顺序交给生成器来处理。
例如使用者需要一共特定车型的实例,生成器负责内部完成组装的细节和顺序,最终把组装好的车型实例交给客户端(使用者)即可。
一般适用场景是,要生成一个相对复杂的对象,这个对象的实现过程遵循某种细节和顺序,客户端不关注这种细节和顺序,或者这种细节和顺序需要对客户端屏蔽。
---------------------------------------------------------------------------------------------------------------------------------
再思考:
Builder模式的主要效果:
1 ) 它使你可以改变一个产品的内部表示 Builder对象提供给导向器一个构造产品的抽象接口。该接口使得生成器可以隐藏这个产品的表示和内部结构。它同时也隐藏了该产品是如何装配的。因为产品是通过抽象接口构造的,你在改变该产品的内部表示时所要做的只是定义一个新的生成器。
建造者模式很容易进行扩展。如果有新的需求,通过实现一个新的建造者类就可以完成,基本上不用修改之前已经测试通过的代码,因此也就不会对原有功能引入风险。
2) 它将构造代码和表示代码分开 Builder模式通过封装一个复杂对象的创建和表示方式提高了对象的模块性。客户不需要知道定义产品内部结构的类的所有信息;这些类是不出现在Builder接口中的。每个Concrete Builder包含了创建和装配一个特定产品的所有代码。这些代码只需要写一次;然后不同的Director可以复用它以在相同部件集合的基础上构作不同的Product。
3 ) 它使你可对构造过程进行更精细的控制 Builder模式与一下子就生成产品的创建型模式不同,它是在导向者的控制下一步一步构造产品的。仅当该产品完成时导向者才从生成器中取回它。因此Builder接口相比其他创建型模式能更好的反映产品的构造过程。这使你可以更精细的控制构建过程,从而能更精细的控制所得产品的内部结构。