一、基础知识:先前学习建造者模式的时候,总是以这个UML图作为学习基础资料
然后总是要记住四个角色
产品类:一般是一个较为复杂的对象,也就是说创建对象的过程比较复杂,一般会有比较多的代码量。在本类图中,产品类是一个具体的类,而非抽象类。实际编程中,产品类可以是由一个抽象类与它的不同实现组成,也可以是由多个抽象类与他们的实现组成。抽象建造者:引入抽象建造者的目的,是为了将建造的具体过程交与它的子类来实现。这样更容易扩展。一般至少会有两个抽象方法,一个用来建造产品,一个是用来返回产品。建造者:实现抽象类的所有未实现的方法,具体来说一般是两项任务:组建产品;返回组建好的产品。导演类:负责调用适当的建造者来组建产品,导演类一般不与产品类发生依赖关系,与导演类直接交互的是建造者类。一般来说,导演类被用来封装程序中易变的部分。住四然后总是要记住四个角色我们可以看到,建造者模式相对工厂方法模式,更加注重产品建造过程,个人认为这才是Builder的核心思想。
二、近日看了一些Builder的例子,再一次觉得设计模式很多时候是一种思想,而不是照搬UML图例子1.1publicclassUser {2PRivatefinalString firstName;//required3privatefinalString lastName;//required4privatefinalintage;//optional5privatefinalString phone;//optional6privatefinalString address;//optional78privateUser(UserBuilder builder) {9this.firstName =builder.firstName;10this.lastName =builder.lastName;11this.age =builder.age;12this.phone =builder.phone;13this.address =builder.address;14}1516publicString getFirstName() {17returnfirstName;18}1920publicString getLastName() {21returnlastName;22}2324publicintgetAge() {25returnage;26}2728publicString getPhone() {29returnphone;30}3132publicString getAddress() {33returnaddress;34}3536publicstaticclassUserBuilder {37privatefinalString firstName;38privatefinalString lastName;39privateintage;40privateString phone;41privateString address;4243publicUserBuilder(String firstName, String lastName) {44this.firstName =firstName;45this.lastName =lastName;46}4748publicUserBuilder age(intage) {49this.age =age;50returnthis;51}5253publicUserBuilder phone(String phone) {54this.phone =phone;55returnthis;56}5758publicUserBuilder address(String address) {59this.address =address;60returnthis;61}6263publicUser build() {64returnnewUser(this);65}6667}68}
当我们试图创建一个user对象的时候
1publicUser getUser() {2returnnew3User.UserBuilder('Jhon', 'Doe')4.age(30)5.phone('1234567')6.address('Fake address 1234')7.build();8}
优点如下:
User构造方法是私有的,这意味着该类不能在客户端代码里直接实例化。User所有属性都是final类型的,在构造方法里面被赋值。只提供了getter方法。builder类使用流式接口风格,让客户端代码阅读起来更容易(见getUser())。builder类构造方法只接收必须属性,为了确保这些属性在构造方法里赋值,只有这些属性被定义成final类型。另外还有一个例子:AlertDialog
1publicclassAlertDialogextendsDialogimplementsDialogInterface {23...45protectedAlertDialog(Context context,inttheme) {6this(context, theme,true);7}89AlertDialog(Context context,inttheme,booleancreateThemeContextWrapper) {10super(context, resolveDialogTheme(context, theme), createThemeContextWrapper);1112mWindow.alwaysReadCloSEOnTouchAttr();13mAlert =newAlertController(getContext(),this, getWindow());14}1516protectedAlertDialog(Context context,booleancancelable, OnCancelListener cancelListener) {17super(context, resolveDialogTheme(context, 0));18mWindow.alwaysReadCloseOnTouchAttr();19setCancelable(cancelable);20setOnCancelListener(cancelListener);21mAlert =newAlertController(context,this, getWindow());22}2324publicstaticclassBuilder {25privatefinalAlertController.AlertParams P;26privateintmTheme;272829publicBuilder(Context context) {30this(context, resolveDialogTheme(context, 0));31}323334publicBuilder(Context context,inttheme) {35P =newAlertController.AlertParams(newContextThemeWrapper(36context, resolveDialogTheme(context, theme)));37mTheme =theme;38}394041publicBuilder setMessage(CharSequence message) {42P.mMessage =message;43returnthis;44}4546publicAlertDialog create() {47finalAlertDialog dialog =newAlertDialog(P.mContext, mTheme,false);48P.apply(dialog.mAlert);49dialog.setCancelable(P.mCancelable);50if(P.mCancelable) {51dialog.setCanceledOnTouchOutside(true);52}53dialog.setOnCancelListener(P.mOnCancelListener);54dialog.setOnDismissListener(P.mOnDismissListener);55if(P.mOnKeyListener !=null) {56dialog.setOnKeyListener(P.mOnKeyListener);57}58returndialog;59}60...61}62}
我们可以看到:AlertDialog的Build是一个静态内部类。AlertDialog设置的属性会暂时保存在Build类的成员变量P(AlertController.AlertParams)中。同时,我们注意到我们设置的属性(如setMessage()),它都回返回本身的AlertBuild对象,这样我们就可以不停地调用它设置的方法(流式接口风格)。
如果我们想获得这个AlertDialog。我们就需要调用建造者的create()方法,在create()方法里面它就会构造出一个Dialog实例,并且将我们刚才设置的属性全部赋给AlertDialog,最后返回AlertDialog的实例
三、总结从上面的UserBuilder和AlertDialog的例子,我们可以做一些总结。Builder设计模式的适用点:
1.产品的属性较多
2.产品本身不可变——Build后,不建议修改产品。
3.产品属性中有部分非必须的属性。
以上三点恰好符合“注重产品创建过程”的Builder核心思想。
参考资料:
http://www.importnew.com/11506.html 建造者模式实践
http://my.oschina.net/weiCloudS/blog/392872?fromerr=AIX2qbD2 在Android中探秘建造者模式