一、基础知识:先前学习建造者模式的时候,总是以这个UML图作为学习基础资料

然后总是要记住四个角色

  • 产品类:一般是一个较为复杂的对象,也就是说创建对象的过程比较复杂,一般会有比较多的代码量。在本类图中,产品类是一个具体的类,而非抽象类。实际编程中,产品类可以是由一个抽象类与它的不同实现组成,也可以是由多个抽象类与他们的实现组成。
  • 抽象建造者:引入抽象建造者的目的,是为了将建造的具体过程交与它的子类来实现。这样更容易扩展。一般至少会有两个抽象方法,一个用来建造产品,一个是用来返回产品。
  • 建造者:实现抽象类的所有未实现的方法,具体来说一般是两项任务:组建产品;返回组建好的产品。
  • 导演类:负责调用适当的建造者来组建产品,导演类一般不与产品类发生依赖关系,与导演类直接交互的是建造者类。一般来说,导演类被用来封装程序中易变的部分。住四然后总是要记住四个角色

我们可以看到,建造者模式相对工厂方法模式,更加注重产品建造过程,个人认为这才是Builder的核心思想。

二、近日看了一些Builder的例子,再一次觉得设计模式很多时候是一种思想,而不是照搬UML图

例子1.

  1. public class User {
  2. private final String firstName; // required
  3. private final String lastName; // required
  4. private final int age; // optional
  5. private final String phone; // optional
  6. private final String address; // optional
  7.  
  8. private User(UserBuilder builder) {
  9. this.firstName = builder.firstName;
  10. this.lastName = builder.lastName;
  11. this.age = builder.age;
  12. this.phone = builder.phone;
  13. this.address = builder.address;
  14. }
  15.  
  16. public String getFirstName() {
  17. return firstName;
  18. }
  19.  
  20. public String getLastName() {
  21. return lastName;
  22. }
  23.  
  24. public int getAge() {
  25. return age;
  26. }
  27.  
  28. public String getPhone() {
  29. return phone;
  30. }
  31.  
  32. public String getAddress() {
  33. return address;
  34. }
  35.  
  36. public static class UserBuilder {
  37. private final String firstName;
  38. private final String lastName;
  39. private int age;
  40. private String phone;
  41. private String address;
  42.  
  43. public UserBuilder(String firstName, String lastName) {
  44. this.firstName = firstName;
  45. this.lastName = lastName;
  46. }
  47.  
  48. public UserBuilder age(int age) {
  49. this.age = age;
  50. return this;
  51. }
  52.  
  53. public UserBuilder phone(String phone) {
  54. this.phone = phone;
  55. return this;
  56. }
  57.  
  58. public UserBuilder address(String address) {
  59. this.address = address;
  60. return this;
  61. }
  62.  
  63. public User build() {
  64. return new User(this);
  65. }
  66.  
  67. }
  68. }

当我们试图创建一个user对象的时候

  1. public User getUser() {
  2. return new
  3. User.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

  1. public class AlertDialog extends Dialog implements DialogInterface {
  2.  
  3. ...
  4.  
  5. protected AlertDialog(Context context, int theme) {
  6. this(context, theme, true);
  7. }
  8.  
  9. AlertDialog(Context context, int theme, boolean createThemeContextWrapper) {
  10. super(context, resolveDialogTheme(context, theme), createThemeContextWrapper);
  11.  
  12. mWindow.alwaysReadCloseOnTouchAttr();
  13. mAlert = new AlertController(getContext(), this, getWindow());
  14. }
  15.  
  16. protected AlertDialog(Context context, boolean cancelable, OnCancelListener cancelListener) {
  17. super(context, resolveDialogTheme(context, 0));
  18. mWindow.alwaysReadCloseOnTouchAttr();
  19. setCancelable(cancelable);
  20. setOnCancelListener(cancelListener);
  21. mAlert = new AlertController(context, this, getWindow());
  22. }
  23.  
  24. public static class Builder {
  25. private final AlertController.AlertParams P;
  26. private int mTheme;
  27.  
  28. public Builder(Context context) {
  29. this(context, resolveDialogTheme(context, 0));
  30. }
  31.  
  32. public Builder(Context context, int theme) {
  33. P = new AlertController.AlertParams(new ContextThemeWrapper(
  34. context, resolveDialogTheme(context, theme)));
  35. mTheme = theme;
  36. }
  37.  
  38. public Builder setMessage(CharSequence message) {
  39. P.mMessage = message;
  40. return this;
  41. }
  42.  
  43. public AlertDialog create() {
  44. final AlertDialog dialog = new AlertDialog(P.mContext, mTheme, false);
  45. P.apply(dialog.mAlert);
  46. dialog.setCancelable(P.mCancelable);
  47. if (P.mCancelable) {
  48. dialog.setCanceledOnTouchOutside(true);
  49. }
  50. dialog.setOnCancelListener(P.mOnCancelListener);
  51. dialog.setOnDismissListener(P.mOnDismissListener);
  52. if (P.mOnKeyListener != null) {
  53. dialog.setOnKeyListener(P.mOnKeyListener);
  54. }
  55. return dialog;
  56. }
  57. ...
  58. }
  59. }

我们可以看到: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中探秘建造者模式

Design Pattern ——Builder的更多相关文章

  1. design pattern Builder 生成器设计模式

    其实设计模式可以学习很有趣,你并不需要有这么难啃旱地FOG对我来说,当然,这些都是健康的骨骼啃啃. 在本文中,建造者模式设计一个搞笑的一幕.根据这一模型来学习功夫的方法,哈哈. 基类的第一,设计.那么 ...

  2. 说说设计模式~大话目录(Design Pattern)

    回到占占推荐博客索引 设计模式(Design pattern)与其它知识不同,它没有华丽的外表,没有吸引人的工具去实现,它是一种心法,一种内功,如果你希望在软件开发领域有一种新的突破,一个质的飞越,那 ...

  3. 设计模式(Design Pattern)系列之.NET专题

    最近,不是特别忙,重新翻了下设计模式,特地在此记录一下.会不定期更新本系列专题文章. 设计模式(Design pattern)是一套被反复使用.多数人知晓的.经过分类编目的.代码设计经验的总结. 使用 ...

  4. [转]Design Pattern Interview Questions - Part 4

    Bridge Pattern, Composite Pattern, Decorator Pattern, Facade Pattern, COR Pattern, Proxy Pattern, te ...

  5. [转]Design Pattern Interview Questions - Part 1

    Factory, Abstract factory, prototype pattern (B) What are design patterns? (A) Can you explain facto ...

  6. C++ Design Pattern: What is a Design Pattern?

    Q: What is a Design Pattern? A: Design Patterns represent solutions to problems what arise when deve ...

  7. Design Pattern in Simple Examples

    Instead of defining what is design pattern lets define what we mean by design and what we mean by pa ...

  8. java设计模式大全 Design pattern samples in Java(最经典最全的资料)

    java设计模式大全 Design pattern samples in Java(最经典最全的资料) 2015年06月19日 13:10:58 阅读数:11100 Design pattern sa ...

  9. [转]Design Pattern Interview Questions - Part 2

    Interpeter , Iterator , Mediator , Memento and Observer design patterns. (I) what is Interpreter pat ...

随机推荐

  1. C# windows窗体程序打包安装及卸载

    一.新建安装部署项目

  2. Oracle的Net Configuration Assistant 配置

    在进行团队开发的时候,一般团队的每一个人只需要安装一个客户端即可,没有必要安装一个Oracle 数据库服务器,而数据库服务器是属于共享的,此时,我们就需要配置客户端.客户端的配置可以有以下两种方式:第 ...

  3. C#.Net参数

    C#.Net参数 阅读目录 引言 形参和实参 命名实参 可选参数 params,数目可变参数 方法解析与重载决策 参数传递      [重难点] ref引用参数/out输出参数   参数修饰符 泛型类 ...

  4. OC & java 对比

    Objective-C的语法对比(和Java的对比)    Objective-C的语法对比(和Java的对比) 1.函数的对比 例子: helloworld方法 Java 语言:     publi ...

  5. 教你如何用Qt做透明的窗体,setMask, Opacity

    // In this function, we can get the height and width of the current widgetvoid Widget::resizeEvent(Q ...

  6. Spring Boot + Elasticsearch

    spring data elasticsearch elasticsearch 2.0.0.RELEASE 2.2.0 1.4.0.M1 1.7.3 1.3.0.RELEASE 1.5.2 1.2.0 ...

  7. !!!全球最流行开源硬件平台!不知道就OUT了!

    全球最流行的几个开源硬件平台!不知道就OUT了! 随着物联网的推广和普及,五年内全球会有200亿台智能设备的需求,而如今随着创客概念的兴起,开源硬件也越加的火热,让我们来看看现在都有哪些主流的开源硬件 ...

  8. 【UIView与控件】

  9. 甲骨文公司 Oracle

    甲骨文公司 甲骨文公司,全称甲骨文股份有限公司,是全球最大的企业软件公司,总部位于美国加利福尼亚州的红木滩.甲骨文是继Microsoft之后,全球收入第二多的软件公司.甲骨文公司1989年正式进入中国 ...

  10. RMQ——忠诚题解

    题目:忠诚 描述: [题目描述] 老管家是一个聪明能干的人.他为财主工作了整整10年,财主为了让自已账目更加清楚.要求管家每天记k次账,由于管家聪明能干,因而管家总是让财主十分满 意.但是由于一些人的 ...