标签:
建造者模式定义:
建造者模式也叫做生成器模式——将一个复杂对象的构建与它的表示分离,使得同样的构建过程可以创建不同的表示。)
例子:我们要生产一个简单车模(汽车模型),汽车模型要有启动、停止、引擎发出声音、喇叭响等功能。现在我要让用户根据自己的喜好来选择这些功能的顺序~(接着上一篇模板方法模式的例子)
我们做出了下面的设计,见UML图
见代码
//汽车模型的抽象类
public abstract class CarModel{
//sequence就是客户要求执行的方法的顺序
private ArrayList<String> sequence = new ArrayList<String>();
protected abstract void start();
protected abstract void stop();
protected abstract void alarm();
protected abstract void engineBoom();
final public void run(){
for(int i = 0; i < this.sequence.size(); ++i){
String actionName = this.sequence.get(i);
if(actionName.equalsIgnoreCase("start")){
this.start();
}else if(actionName.equalsIgnoreCase("stop")){
this.stop();
}else if(actionName.equalsIgnoreCase("alarm")){
this.alarm();
}else if(actionName.equalsIgnoreCase("engine boom")){
this.engineBoom();
}
}
}
final public void setSequence(ArrayList<String> sequence){
this.sequence = sequence;
}
}
//Benz模型
public class BenzModel extends CarModel {
@Override
protected void start() {
System.out.println("奔驰车开始跑。。。");
}
@Override
protected void stop() {
System.out.println("奔驰车停下。。。");
}
@Override
protected void alarm() {
System.out.println("奔驰车喇叭响...");
}
@Override
protected void engineBoom() {
System.out.println("奔驰车的引擎发出声音了。。。");
}
}
//宝马模型
public class BMWModel extends CarModel {
@Override
protected void start() {
System.out.println("宝马车开始跑。。。");
}
@Override
protected void stop() {
System.out.println("宝马车停下。。。");
}
@Override
protected void alarm() {
System.out.println("宝马车喇叭响...");
}
@Override
protected void engineBoom() {
System.out.println("宝马车的引擎发出声音了。。。");
}
}
public class Client {
public static void main(String[] args) {
BenzModel benz = new BenzModel();
ArrayList<String> sequence = new ArrayList<String>();
sequence.add("engine boom");//客户要求,引擎先发出声音
sequence.add("start");//开始跑
sequence.add("stop");
benz.setSequence(sequence);
benz.run();
}
}
ok,我们现在的设计能够满足客户的要求。可是如果有N个用户呢?可能你需要设计N个场景类来满足。当N=1000000000000时…….怎么办呢?
1、新加一个导演类!导演这里有所有的顺序,这样就可以避免根据客户临时提出来的需求来设计而手忙脚乱了。同时导演类起到封装的作用,避免高层模块深入到建造者内部的实现类。当建造者模式很大时,导演类可以有很多个。
2、然后再新加一个建造者类,建造者根据导演类的要求来生产具体的对象。
见UML图,(UML图有点小问题——导演类聚合多个汽车建造者,但不影响理解)
见代码`
//产品类——汽车模型不变
public abstract class CarModel{
private ArrayList<String> sequence = new ArrayList<String>();
protected abstract void start();
protected abstract void stop();
protected abstract void alarm();
protected abstract void engineBoom();
final public void run(){
for(int i = 0; i < this.sequence.size(); ++i){
String actionName = this.sequence.get(i);
if(actionName.equalsIgnoreCase("start")){
this.start();
}else if(actionName.equalsIgnoreCase("stop")){
this.stop();
}else if(actionName.equalsIgnoreCase("alarm")){
this.alarm();
}else if(actionName.equalsIgnoreCase("engine boom")){
this.engineBoom();
}
}
}
final public void setSequence(ArrayList<String> sequence){
this.sequence = sequence;
}
}
public class BMWModel extends CarModel {
@Override
protected void start() {
System.out.println("宝马车开始跑。。。");
}
@Override
protected void stop() {
System.out.println("宝马车停下。。。");
}
@Override
protected void alarm() {
System.out.println("宝马车喇叭响...");
}
@Override
protected void engineBoom() {
System.out.println("宝马车的引擎发出声音了。。。");
}
}
public class BenzModel extends CarModel {
@Override
protected void start() {
System.out.println("奔驰车开始跑。。。");
}
@Override
protected void stop() {
System.out.println("奔驰车停下。。。");
}
@Override
protected void alarm() {
System.out.println("奔驰车喇叭响...");
}
@Override
protected void engineBoom() {
System.out.println("奔驰车的引擎发出声音了。。。");
}
//我们新增的汽车建造者抽象类
public abstract class CarBuilder {
public abstract void setSequence(ArrayList<String> sequence);
public abstract CarModel getCarModel();
}
//宝马建造者实现类
public class BMWBuilder extends CarBuilder {
private BMWModel bmw;
@Override
public void setSequence(ArrayList<String> sequence) {
this.bmw.setSequence(sequence);
}
@Override
public CarModel getCarModel() {
// TODO Auto-generated method stub
return bmw;
}
}
//奔驰建造者实现类
public class BenzBuilder extends CarBuilder {
private BenzModel benz = new BenzModel();
@Override
public void setSequence(ArrayList<String> sequence) {
this.benz.setSequence(sequence);
}
@Override
public CarModel getCarModel() {
return benz;
}
}
//导演类
public class Director {
private ArrayList<String> sequence = new ArrayList<String>();
private BenzBuilder benzBuilder = new BenzBuilder();
private BMWBuilder bmwBuilder = new BMWBuilder();
public BenzModel getABenzModel(){
this.sequence.clear();
this.sequence.add("start");
this.sequence.add("stop");
this.benzBuilder.setSequence(sequence);
return (BenzModel)this.benzBuilder.getCarModel();
}
public BenzModel getBBenzModel(){
this.sequence.clear();
this.sequence.add("start");
this.sequence.add("alarm");
this.sequence.add("stop");
this.benzBuilder.setSequence(sequence);
return (BenzModel)this.benzBuilder.getCarModel();
}
//好多种...
}
//场景类
public class Client {
public static void main(String[] args) {
Director director = new Director();
for(int i = 0; i < 10; ++i){
director.getABenzModel().run();
}
for(int i = 0; i < 10; ++i){
director.getBBenzModel().run();
}
}
}
建造者模式也是有通用类图的,这个建议自己尝试一下~
建造者模式的优点
便于控制细节风险。因为具体的建造者是独立的,因此可以对建造过程逐步细化,而不对其他的模块产生影响。
建造者模式的使用场景
相同的方法,不同的顺序,产生不同的事件结果时
建造者模式的注意事项
标签:
原文地址:http://blog.csdn.net/tyronerenekton/article/details/52289842