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

然后总是要记住四个角色
- 产品类:一般是一个较为复杂的对象,也就是说创建对象的过程比较复杂,一般会有比较多的代码量。在本类图中,产品类是一个具体的类,而非抽象类。实际编程中,产品类可以是由一个抽象类与它的不同实现组成,也可以是由多个抽象类与他们的实现组成。
- 抽象建造者:引入抽象建造者的目的,是为了将建造的具体过程交与它的子类来实现。这样更容易扩展。一般至少会有两个抽象方法,一个用来建造产品,一个是用来返回产品。
- 建造者:实现抽象类的所有未实现的方法,具体来说一般是两项任务:组建产品;返回组建好的产品。
- 导演类:负责调用适当的建造者来组建产品,导演类一般不与产品类发生依赖关系,与导演类直接交互的是建造者类。一般来说,导演类被用来封装程序中易变的部分。住四然后总是要记住四个角色
我们可以看到,建造者模式相对工厂方法模式,更加注重产品建造过程,个人认为这才是Builder的核心思想。
二、近日看了一些Builder的例子,再一次觉得设计模式很多时候是一种思想,而不是照搬UML图
例子1.
public class User {
private final String firstName; // required
private final String lastName; // required
private final int age; // optional
private final String phone; // optional
private final String address; // optional
private User(UserBuilder builder) {
this.firstName = builder.firstName;
this.lastName = builder.lastName;
this.age = builder.age;
this.phone = builder.phone;
this.address = builder.address;
}
public String getFirstName() {
return firstName;
}
public String getLastName() {
return lastName;
}
public int getAge() {
return age;
}
public String getPhone() {
return phone;
}
public String getAddress() {
return address;
}
public static class UserBuilder {
private final String firstName;
private final String lastName;
private int age;
private String phone;
private String address;
public UserBuilder(String firstName, String lastName) {
this.firstName = firstName;
this.lastName = lastName;
}
public UserBuilder age(int age) {
this.age = age;
return this;
}
public UserBuilder phone(String phone) {
this.phone = phone;
return this;
}
public UserBuilder address(String address) {
this.address = address;
return this;
}
public User build() {
return new User(this);
}
}
}
当我们试图创建一个user对象的时候
public User getUser() {
return new
User.UserBuilder('Jhon', 'Doe')
.age(30)
.phone('1234567')
.address('Fake address 1234')
.build();
}
优点如下:
- User构造方法是私有的,这意味着该类不能在客户端代码里直接实例化。
- User所有属性都是final类型的,在构造方法里面被赋值。只提供了getter方法。
- builder类使用流式接口风格,让客户端代码阅读起来更容易(见getUser())。
- builder类构造方法只接收必须属性,为了确保这些属性在构造方法里赋值,只有这些属性被定义成final类型。
另外还有一个例子:
AlertDialog
public class AlertDialog extends Dialog implements DialogInterface {
...
protected AlertDialog(Context context, int theme) {
this(context, theme, true);
}
AlertDialog(Context context, int theme, boolean createThemeContextWrapper) {
super(context, resolveDialogTheme(context, theme), createThemeContextWrapper);
mWindow.alwaysReadCloseOnTouchAttr();
mAlert = new AlertController(getContext(), this, getWindow());
}
protected AlertDialog(Context context, boolean cancelable, OnCancelListener cancelListener) {
super(context, resolveDialogTheme(context, 0));
mWindow.alwaysReadCloseOnTouchAttr();
setCancelable(cancelable);
setOnCancelListener(cancelListener);
mAlert = new AlertController(context, this, getWindow());
}
public static class Builder {
private final AlertController.AlertParams P;
private int mTheme;
public Builder(Context context) {
this(context, resolveDialogTheme(context, 0));
}
public Builder(Context context, int theme) {
P = new AlertController.AlertParams(new ContextThemeWrapper(
context, resolveDialogTheme(context, theme)));
mTheme = theme;
}
public Builder setMessage(CharSequence message) {
P.mMessage = message;
return this;
}
public AlertDialog create() {
final AlertDialog dialog = new AlertDialog(P.mContext, mTheme, false);
P.apply(dialog.mAlert);
dialog.setCancelable(P.mCancelable);
if (P.mCancelable) {
dialog.setCanceledOnTouchOutside(true);
}
dialog.setOnCancelListener(P.mOnCancelListener);
dialog.setOnDismissListener(P.mOnDismissListener);
if (P.mOnKeyListener != null) {
dialog.setOnKeyListener(P.mOnKeyListener);
}
return dialog;
}
...
}
}
我们可以看到: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的更多相关文章
- design pattern Builder 生成器设计模式
其实设计模式可以学习很有趣,你并不需要有这么难啃旱地FOG对我来说,当然,这些都是健康的骨骼啃啃. 在本文中,建造者模式设计一个搞笑的一幕.根据这一模型来学习功夫的方法,哈哈. 基类的第一,设计.那么 ...
- 说说设计模式~大话目录(Design Pattern)
回到占占推荐博客索引 设计模式(Design pattern)与其它知识不同,它没有华丽的外表,没有吸引人的工具去实现,它是一种心法,一种内功,如果你希望在软件开发领域有一种新的突破,一个质的飞越,那 ...
- 设计模式(Design Pattern)系列之.NET专题
最近,不是特别忙,重新翻了下设计模式,特地在此记录一下.会不定期更新本系列专题文章. 设计模式(Design pattern)是一套被反复使用.多数人知晓的.经过分类编目的.代码设计经验的总结. 使用 ...
- [转]Design Pattern Interview Questions - Part 4
Bridge Pattern, Composite Pattern, Decorator Pattern, Facade Pattern, COR Pattern, Proxy Pattern, te ...
- [转]Design Pattern Interview Questions - Part 1
Factory, Abstract factory, prototype pattern (B) What are design patterns? (A) Can you explain facto ...
- 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 ...
- 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 ...
- java设计模式大全 Design pattern samples in Java(最经典最全的资料)
java设计模式大全 Design pattern samples in Java(最经典最全的资料) 2015年06月19日 13:10:58 阅读数:11100 Design pattern sa ...
- [转]Design Pattern Interview Questions - Part 2
Interpeter , Iterator , Mediator , Memento and Observer design patterns. (I) what is Interpreter pat ...
随机推荐
- Testlink接口使用方法-python语言远程调用
deepin@deepin-pc:~/test$ cat libclienttestlink.py #!/usr/bin/env python3 # -*- coding: utf-8 -*- #! ...
- ExtJs5_使用图标字体来美化按钮
sencha 的例子中,有使用图标字体来美化按钮的例子,这个用起来又方便风格又统一,例如下图: 上面图标字体的使用方法也很简单,只要下载Font Awesome的css和图标文件,放到项目里就可以了. ...
- 转:Git_Windows 系统下Git安装图解
原文地址:http://blog.csdn.net/jiguanghoverli/article/details/7902791 Windows 系统下Git安装图解 简单来说Git是一个免费的.开源 ...
- 【Maven实战】传递性依赖的问题
在上一篇文章中我们已经介绍了依赖性,这次我们再来介绍下传递依赖的问题,首先我们还是在上篇文章基础之上进行编写. 1.上篇文章中已经建立了一个user-core的模块,现在首先再建立一个user-log ...
- Delphi 缩放图像代码 - 支持PNG透明通道(利用了Windows的windowscodecs.dll)
要求Delphi2007或者更高版本, 系统要求至少XP-SP2以上 实际上是利用了Windows的windowscodecs.dll这个文件的功能 在VCL里已经封装为TWICImage类 proc ...
- 【HDOJ】1506 Largest Rectangle in a Histogram
Twitter还是Amazon拿这个题目当过面试题.DP区间求面积. /* 1506 */ #include <cstdio> #include <cstring> #incl ...
- Android 各版本信息 (维基百科)
The following tables show the release dates and key features of all Android operating system updates ...
- DLL入门浅析(1)——如何建立DLL
转载自:http://www.cppblog.com/suiaiguo/archive/2009/07/20/90619.html 初学DLL,结合教程,总结一下自己的所得,希望对DLL初学者们有所帮 ...
- HDU_1401——分步双向BFS,八进制位运算压缩,map存放hash
Problem Description Solitaire is a game played on a chessboard 8x8. The rows and columns of the ches ...
- [Java I/O] TextFile 工具类
一种常见的编程任务是,从一个文件读取内容,修改内容,再把内容写到另一个文件里. Java 要实现读取.写入操作,需要创建多个类才能产生一个 Stream 进行操作. 下面是一个简单的工具类,封装对文件 ...