面向对象:建造者(Builder)模式
2009-11-08 22:19
387 查看
以下内容来自http://www.lifevv.com/sysdesign/index.html
本文介绍设计模式中的建造者(Builder)模式的概念,用法,以及实际应用中怎么样使用Builder模式进行开发。Builder模式的概念
Builder模式是一种对象创建型模式,它跟工厂模式(包括工厂方法模式与虚拟工厂模式)一样,都用来创建类的对象。我们先阐述一下Builder模式的定义
:
Builder模式用来创建复合对象,并把复合对象的创建过程加以抽象,通过子类继承和重载的方式,动态地创建具有复合属性的对象;另一方面,为了统一创建过程,又把对象创建的操作统一封装在名为Director所提供的方法里。
复合对象的概念:
所
谓复合对象,指有别于一般的对象,该对象具有不同的复合属性。比如我们把一辆汽车看成一个复合对象,是因为该汽车由多个复杂的零部件组成,这些零部件可能
因为生产厂家的不同等等而不同,但这些不同的零部件最终都能被组装为一辆汽车。这些不同的零部件我们可称之为汽车的复合属性,同样可称该汽车为一个复合对
象。
我们再用类图来说明Builder模式的结构,如图:
[该图出自维基百科wikipedia.org]
图示,
- Builder#buildPart方法(不同部分的创建都是一个buildPart方法)用来创建产品Product的各部分;
- ConcreteBuilder为继承自Builder的具体的创建类;
- Builder#getResult或ConcreteBuilder#getResult返回最终被创建的复合对象;
- Product为被创建的产品对象;
- Director#construct方法是对整个产品创建过程的封装;该方法内部将调用Builder#buildPart方法;一个典型的construct方法实现可能为:
public void construct(Builder builder) {
builder.buildPart1();
builder.buildPart2();
...
}
有时为了简便,又可把Director与ConcreteBuilder合并为一个类。
Builder模式与工厂模式的区别与Builder模式的应用场景
我们上面提到了,Builder模式和工厂模式一样,都属于对象创建型模式,都用来创建类的对象。但它们存在在本质的区别:
- 在工厂模式里,我们无需关心产品的各部分是如何被创建的;但在Builder模式里,会把产品的创建过程抽象为多个部分。也就是说,工厂模式被关注的是整个产品,而Builder模式被关注的是产品的组成部分的创建过程。
- 因为上述关注点的不一样,工厂模式被创建的产品是一个单一产品;Builder模式创建的是一个复合产品。
简单一点说,在具体的应用中,我们是选用工厂模式来创建对象呢还是选用Builder模式来创建对象,完全取决于我们的关注点。
比如同为创建一辆汽车,如果我们只需关注只是从工厂里造出的这一辆汽车本身(然后加以使用),我们就可以使用工厂模式来创建该汽车;但如果我们还应该关注该汽车的各部分是怎么造出来的(或者说,不同的工厂对产品的各部分的造法不一样),我们就应该使用Builder模式。
Builder模式的应用场景
- 对象的创建:Builder模式是为对象的创建而设计的模式
- 创建的是一个复合对象:被创建的对象为一个具有复合属性的复合对象
- 关注对象创建的各部分的创建过程:不同的工厂(这里指builder生成器)对产品属性有不同的创建方法
Builder模式的应用范例
下面我们举个例子来加深我们对Builder模式的理解。
比如我们要通过一个汽车加工厂,组装一辆汽车;汽车由车头,车身,车尾3部分组成;它的基本组装步骤是:
- 组装车头
- 组装车身
- 组装车尾
不管被组装的是吉普车,卡车,还是公交车,它们都可以各自重新定义车头,车身与车尾的组装方法;而通过这些被重新定义的组装方法,通过相同的组装步骤就可以组装具有不同属性的各类汽车了。
通过上面的分析,我们知道,该范例满足Builder模式的应用场景所提到的条件:
- 对象的创建:我们需要创建汽车对象
- 创建的是一个复合对象:我们需要创建的汽车对象是具有车头,车身,车尾等复合属性的复合对象
- 关注对象创建的各部分的创建过程:吉普车,卡车等对车头,车身,车尾的组装方法不尽相同
下面我们用Builder设计模式来抽象以上组装过程:
- CarDirector:汽车组装操作的封装类
- CarBuilder:汽车组装抽象类
- JeepBuilder:吉普车组装类,继承自CarBuilder类。
- Car:汽车类,包括车头,车身,车尾等属性。相当于产品类。由CarBuilder/JeepBuilder等创建。
源代码
<!--//
function _syboos_pmplat_setUpCode() {
//dp.SyntaxHighlighter.ClipboardSwf = 'js/clipboard.swf';
dp.SyntaxHighlighter.HighlightAll('_syboos_pmplat_code');
}
window.onload=_syboos_pmplat_setUpCode;
//-->
//汽车类
public
class
Car {
//车头
private
String head;
//车身
private
String body;
//车尾
private
String tail;
public
String getBody() {
return
body;
}
public
void
setBody(String body) {
this
.body = body;
}
public
String getHead() {
return
head;
}
public
void
setHead(String head) {
this
.head = head;
}
public
String getTail() {
return
tail;
}
public
void
setTail(String tail) {
this
.tail = tail;
}
}
//汽车组装抽象类
public
abstract
class
CarBuilder {
//组装车头
public
abstract
void
makeHead();
//组装车身
public
abstract
void
makeBody();
//组装车尾
public
abstract
void
makeTail();
//得到被组装好的汽车对象
public
abstract
Car getCar();
}
//吉普车组装类
public
class
JeepBuilder
extends
CarBuilder {
Car car = new
Car();
//组装车头
public
void
makeHead() {
car.setHead("Jeep head"
);
}
//组装车身
public
void
makeBody() {
car.setHead("Jeep body"
);
}
//组装车尾
public
void
makeTail() {
car.setHead("Jeep tail"
);
}
public
Car getCar() {
return
car;
}
}
//汽车组装操作的封装类:该类封装了对整个汽车的组装操作
public
class
CarDirector {
//汽车的组装操作
public
void
makeCar(CarBuilder builder) {
//组装车头
builder.makeHead();
//组装车身
builder.makeBody();
//组装车尾
builder.makeTail();
}
}
//调用
public
class
Client {
public
static
void
main(String[] args) {
CarDirector director = new
CarDirector();
//创建吉普车生成器(工厂)
CarBuilder b = new
JeepBuilder();
//调用CarDirector组装整个汽车
director.makeCar(b);
//得到组装好的汽车
Car car = b.getCar();
System.out.println(car.getHead());
System.out.println(car.getBody());
System.out.println(car.getTail());
}
}
//汽车类 public class Car { //车头 private String head; //车身 private String body; //车尾 private String tail; public String getBody() { return body; } public void setBody(String body) { this.body = body; } public String getHead() { return head; } public void setHead(String head) { this.head = head; } public String getTail() { return tail; } public void setTail(String tail) { this.tail = tail; } } //汽车组装抽象类 public abstract class CarBuilder { //组装车头 public abstract void makeHead(); //组装车身 public abstract void makeBody(); //组装车尾 public abstract void makeTail(); //得到被组装好的汽车对象 public abstract Car getCar(); } //吉普车组装类 public class JeepBuilder extends CarBuilder { Car car = new Car(); //组装车头 public void makeHead() { car.setHead("Jeep head"); } //组装车身 public void makeBody() { car.setHead("Jeep body"); } //组装车尾 public void makeTail() { car.setHead("Jeep tail"); } public Car getCar() { return car; } } //汽车组装操作的封装类:该类封装了对整个汽车的组装操作 public class CarDirector { //汽车的组装操作 public void makeCar(CarBuilder builder) { //组装车头 builder.makeHead(); //组装车身 builder.makeBody(); //组装车尾 builder.makeTail(); } } //调用 public class Client { public static void main(String[] args) { CarDirector director = new CarDirector(); //创建吉普车生成器(工厂) CarBuilder b = new JeepBuilder(); //调用CarDirector组装整个汽车 director.makeCar(b); //得到组装好的汽车 Car car = b.getCar(); System.out.println(car.getHead()); System.out.println(car.getBody()); System.out.println(car.getTail()); } }
运行并显示Client:
C:/builder>javac *.java
C:/builder>java Client
Jeep head
Jeep body
Jeep tail
C:/builder>
上面演示了吉普车(Jeep)的生产过程,如果需要创建公交车(Bus),我们可以依葫芦画瓢,使用一个继承自CarBuilder的BusBuilder,便可简单地生产一个具有与吉普车不同的车头,车身,车尾的汽车来。
Builder模式与Template Method模式的区别
我们在
设计模式之Template Method - 模板方法模式
一文中对Template Method模式作了介绍,细心的读者可能会发现,这2种模式中我们举了有点类似的范例:通过汽车加工厂组装汽车(车头,车身,车尾)来说明这2种模式。
但他们之间存在本质的区别:
- Template Method模式只是继承的关系,Builder模式与Factory Method模式一样,除了继承之外,还有有创建的过程。
-
Template
Method模式强调的是操作(固定的步骤操作与不同的算法细节),而Builder模式除了强调动作(创建对象的各部分)之外,还强调了整个对象的生
成。这是他们之间的本质区别,Builder模式是一种对象创建型设计模式,Template Method是动作型模式。
Builder模式小结
Builder模式是一种注重对象创建细节的设计模式,它被用来动态创建复合对象。
相关文章推荐
- 设计模式(Design Patterns)-可复用面向对象软件的基础 04:建造者模式(Builder)
- 面向对象设计模式之---建造者模式(Builder Pattern)
- 面向对象设计模式学习---Builder模式(创建型)
- 建造者模式-Builder Pattern 复杂对象的组装与创建——建造者模式(三):关于Director的进一步讨论,建造者模式总结
- C#面向对象设计模式学习笔记(3) - Builder 生成器模式(创建型模式)
- 可复用面向对象软件基础——设计模式(五)之建造者模式
- js原生设计模式——6复杂对象的构建—Builder建造者模式
- Builder生成器(创建型设计模式)面向对象设计模式纵横谈讲座笔记之四
- 建造者模式-Builder Pattern 复杂对象的组装与创建——建造者模式(二):游戏角色设计的建造者模式解决方案
- Builder模式中,为什么必须在对象域而不是builder域中检查参数?
- 设计模式——建造者(Builder)模式
- Builder(生成器)---对象创建型模式
- 设计模式:面向对象基础
- 面向对象之this、static和单例设计模式
- [设计模式]面向对象设计原则之迪米特法则(最少知道法则)
- C#设计模式之建造者(Builder)模式示例源代码
- Java设计模式(5)——创建型模式之建造者模式(Builder)
- 面向对象设计原则与模式摘录
- Builder:建造者模式
- 设计模式之面向对象基础