建造者模式
建造者模式:也叫作生成器模式,将一个复杂对象的创建与它的表示分离,使得同样的构建过程可以创建不同的表示(Separate the construction of a complex object from its representation so that the same construction process can create different representations)。
建造者模式中有4个角色,其通用类图如下:
Product产品类:通常是实现了模板方法模式,也就是有模板方法和基本方法。通常以抽象类和具体类(类图中省略了抽象类)。参考详细例子中的BenzModel和BMWModel类。
Builder抽象建造者:规范产品的组建,定义抽象方法,一般由具体的构建子类实现。详细例子中的CarBuilder就属于抽象建造者。
ConcreteBuilder具体建造者:实现抽象类定义的所有方法,并且返回一个组建好的对象。参见详细例子中的BenBuilder和BMWBuilder。
Director导演类:负责安排已有模板的顺序,然后传递给Builder开始建造。
建造者的通用源码如下:
public class Product {
private void doSomething(){
//产品的业务处理
}}
public abstract class Builder {
//设置产品的不同部分,以获得不同的产品
public abstract void setPart();
//建造产品
public abstract Product buildProduct();}
public class ConcreteBuilder extends Builder{
private Product product = new Product();
@Override
public void setPart() {
// TODO Auto-generated method stub
//产品类内部的逻辑处理
}
@Override
public Product buildProduct() {
// TODO Auto-generated method stub
return product;
}}
public class Director {
private Builder builder = new ConcreteBuilder();
public Product getProduct(){
builder.setPart();
return builder.buildProduct();
}}
详细例子的通用类图和源码如下:
public abstract class CarModel {
private ArrayList<String> sequence = new ArrayList<String>();
protected abstract void start();
protected abstract void alarm();
protected abstract void stop();
final public void run(){
for(int i = 0; i < sequence.size(); i++){
String actionName = sequence.get(i);
if(actionName.equalsIgnoreCase("start")){
this.start();
}else if(actionName.equalsIgnoreCase("stop")){
this.stop();
}else if(actionName.equalsIgnoreCase("alarm")){
this.alarm();
}
}
}
final public void setSequence(ArrayList<String> sequence){
this.sequence = sequence;
}}
public class BenzModel extends CarModel{
@Override
protected void start() {
// TODO Auto-generated method stub
System.out.println("奔驰车启动");
}
@Override
protected void alarm() {
// TODO Auto-generated method stub
System.out.println("奔驰车鸣笛");
}
@Override
protected void stop() {
// TODO Auto-generated method stub
System.out.println("奔驰车停止");
}}
public class BMWModel extends CarModel{
@Override
protected void start() {
// TODO Auto-generated method stub
System.out.println("宝马车启动");
}
@Override
protected void alarm() {
// TODO Auto-generated method stub
System.out.println("宝马车鸣笛");
}
@Override
protected void stop() {
// TODO Auto-generated method stub
System.out.println("宝马车停止");
}}
public abstract class CarBuilder {
protected abstract void setSequence(ArrayList<String> sequence);
protected abstract CarModel getCarModel();}
public class BenzBuilder extends CarBuilder{
private BenzModel benz = new BenzModel();
@Override
protected void setSequence(ArrayList<String> sequence) {
// TODO Auto-generated method stub
benz.setSequence(sequence);
}
@Override
protected CarModel getCarModel() {
// TODO Auto-generated method stub
return this.benz;
}}
public class BMWBuilder extends CarBuilder{
private BMWModel bmw = new BMWModel();
@Override
protected void setSequence(ArrayList<String> sequence) {
// TODO Auto-generated method stub
bmw.setSequence(sequence);
}
@Override
protected CarModel getCarModel() {
// TODO Auto-generated method stub
return this.bmw;
}}
public class Director {
private ArrayList<String> sequence = new ArrayList<String>();
private BenzBuilder benz = new BenzBuilder();
private BMWBuilder bmw = new BMWBuilder();
public BenzModel getBenzModel(){
this.sequence.clear();
this.sequence.add("start");
this.sequence.add("stop");
benz.setSequence(sequence);
return (BenzModel)benz.getCarModel();
}
public BMWModel getBMWModel(){
this.sequence.clear();
this.sequence.add("start");
this.sequence.add("alarm");
this.sequence.add("stop");
this.bmw.setSequence(sequence);
return (BMWModel)this.bmw.getCarModel();
}}
public class Client {
/**
* @param args
*/
public static void main(String[] args) {
// TODO Auto-generated method stub
Director director = new Director();
director.getBenzModel().run();
director.getBMWModel().run();
}}
View Code
建造者模式的优点
封装性:使用建造者模式可以使客户端不必知道产品内部组成的细节,如例子中我们不必关系每一个具体的模型内部是如何实现的,产生的对象类型就是CarModel。
建造者独立,容易扩展,BenzBuilder和BMWBuilder相互独立,有利于系统扩展。
便于控制细节风险,由于具体的建造者是独立的,因此可以对建造过程逐步细化,而不对其他的模块产生任何影响。
建造者模式的使用场景
相同的方法,不同的执行顺序,产生不同的事件结果,可以采用建造者模式;
多个部件或零件都可以装配到一个对象中,但是产生的运行结果又不相同时,则可以使用该模式;
产品类非常复杂,或者产品类中的顺序不同产生不同的效能,则可以使用建造者模式;
在对象创建过程中会使用到系统中的一些其它对象,这些对象在产品对象的创建过程中不易得到时,也可以采用建造者模式封装该对象的创建过程。该种场景只能是一个补偿方法,因为一个对象不容易获得,而在设计阶段竟然没有发觉,而要通过创建者模式柔化创建过程,本身就违反了设计的最初目标。
最佳实践
本文中列举的实例,通过将建造者模式和模板方法模式进行结合,就是一个对建造者模式很好的扩展实践。

Comments | NOTHING