* 24种设计模式——建造者模式

来源:互联网 发布:弘扬软件股份有限公司 编辑:程序博客网 时间:2024/05/19 01:58

将一个复杂对象的创建与它的表示分离,使得同样的构建过程可以创建不同的表示。


建造者模式的核心:组装顺序不同对象效能不同。(内置模板方法模式)


建造者模式和工厂模式的区别:

建造者模式最主要功能是基本方法的调用顺序安排,也就是这些基本方法已经实现了,通俗地说就是零件的装配,顺序不同产生的对象也不同。

工厂模式重点就是创建,创建零件是它的主要职责,组装顺序不是它关心的。

一、建造可run出不同顺序的汽车

1. 车辆模型的抽象类

public abstract class CarModel {//这个参数是各个基本方法执行的顺序private List<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();}}}public void setSequence(List<String> sequence) {this.sequence = sequence;}}

2. 奔驰模型代码

public class BenzModel extends CarModel{protected void start() {System.out.println("奔驰车跑起来了!");}protected void stop() {System.out.println("奔驰车应该这样停车!");}protected void alarm() {System.out.println("奔驰车的喇叭声音是这个样子的!");}protected void engineBoom() {System.out.println("奔驰车的引擎是这个样子的");}}
3. 宝马模型代码

public class BMWModel extends CarModel{protected void start() {System.out.println("宝马车跑起来了!");}protected void stop() {System.out.println("宝马车应该这样停车!");}protected void alarm() {System.out.println("宝马车的喇叭声音是这个样子的!");}protected void engineBoom() {System.out.println("宝马车的引擎是这个样子的");}}
4. 奔驰模型代码

public class Client {public static void main(String[] args) {CarModel benz = new BenzModel();//存放run的顺序List<String> sequence = new ArrayList<String>();sequence.add("engine boom");sequence.add("start");sequence.add("stop");benz.setSequence(sequence);benz.run();}}

5. 这里我们只满足了一个需要,如果有100个不同需求,我们就要一个个地写场景类来满足吗?不,可以为每种模型产品定义一个建造者,有啥顺序直接告诉建造者,由建造者来建造。

6. 抽象汽车组装者

public abstract class CarBuilder {//建造一个模型,你要给我一个顺序要求,就是组装顺序public abstract void setSequence(List<String> sequence);//设置完毕后,就可以直接拿到这个车辆模型public abstract CarModel getCharModel();}
7. 奔驰车组装者

public class BenzBuilder extends CarBuilder{private BenzModel benz = new BenzModel();public void setSequence(List<String> sequence) {this.benz.setSequence(sequence);}public CarModel getCharModel() {return this.benz;}}
8. 宝马车组装者

public class BMWBuilder extends CarBuilder{BMWModel bmw = new BMWModel();public void setSequence(List<String> sequence) {this.bmw.setSequence(sequence);}public CarModel getCharModel() {return bmw;}}
9. 修改后的场景类

public class Client {public static void main(String[] args) {/* * 客户告诉XX公司,我要这样一个模型,然后XX公司就告诉老大说要这样一个模型,这样一个顺序,然后我就来制造 *///存放run的顺序List<String> sequence = new ArrayList<String>();sequence.add("engine boom");sequence.add("start");sequence.add("stop");//要一个奔驰车BenzBuilder benzBuilder = new BenzBuilder();//把顺序给这个builder类,制造出这样一个车出来benzBuilder.setSequence(sequence);//制造出一个奔驰车BenzModel benz = (BenzModel) benzBuilder.getCharModel();benz.run();//按照同样的顺序,我再要一个宝马BMWBuilder bwmBuilder = new BMWBuilder();bwmBuilder.setSequence(sequence);BMWModel bmw = (BMWModel) bwmBuilder.getCharModel();bmw.run();}}
10. 定义几种车类型,要什么类型,马上批产 —— 终级模型

                                                                 clip_image006

11. 导演类

public class Director {private List<String> sequence = new ArrayList();private CarBuilder benzBuilder = new BenzBuilder();private BMWBuilder bmwBuilder = new BMWBuilder();/* * A类型奔驰车模型,start-stop */public BenzModel getABenzModel(){//清理场景,这里是一些初级程序员不注意的地方this.sequence.clear();//ABenzModel的执行顺序this.sequence.add("start");this.sequence.add("stop");//按照顺序返回一个奔驰车this.benzBuilder.setSequence(sequence);return (BenzModel) this.benzBuilder.getCharModel();}/* * B类奔驰车,engine boom-start-stop */public BenzModel getBBenzModel(){this.sequence.clear();this.sequence.add("engine boom");this.sequence.add("start");this.sequence.add("stop");this.benzBuilder.setSequence(sequence);return (BenzModel) this.benzBuilder.getCharModel();}/* * C类宝马,start..... */public BMWModel getCBMWModel(){this.sequence.clear();this.sequence.add("start");this.bmwBuilder.setSequence(sequence);return (BMWModel) this.bmwBuilder.getCharModel();}}
12. 导演类

public class Client {public static void main(String[] args) {Director director = new Director();//1万辆A类奔驰车for(int i = 0;i < 10000;i++){director.getABenzModel().run();}//100万辆B类奔驰车for(int i = 0;i < 1000000;i++){director.getBBenzModel().run();}//1000万辆C类型的宝马车for(int i = 0;i < 10000000;i++){director.getCBMWModel().run();}}}

二、建造者模式的定义

                                                                            clip_image008

1. 产品类(通常是实现了模板方法模式

public class Product {public void doSomething(){//独立的业务处理}}
2. 抽象建造者

public abstract class Builder {//设置产品不同部分,以获得不同的产品public abstract void setPart();//建造产品public abstract Product buildProduct();}
3. 具体建造者(有多个产品类就有几个具体的建造者,而且这多个产品类具有相同接口或抽象类)

public class ConcreteProduct extends Builder{private Product product = new Product();//设置产品零件public void setPart() {/* * 产品类内的逻辑处理 */}//组建一个产品public Product buildProduct() {return product;}}
4. 导演类

public class Director1 {private Builder builder = new ConcreteProduct();//构造不同的产品public Product getAProduct(){builder.setPart();/* * 设置不同的零件,产生不同的产品 */return builder.buildProduct();}}
导演类起到封装的作用,避免高层模块深入到建造者司令部的实现类。在建造者模式比较庞大时,导演类可以有多个。

三、 建造者模式的应用

1. 封装性

使用建造者模式可以使客户端不必知道产品内部组成的细节。

2. 建造者独立,容易扩展

例子中的BenzBuilder和BMWBuilder是相互独立的,对系统 的扩展非常有利。

四、 使用场景

1. 相同的方法,不同的执行顺序,产生不同的事件结果时,可以采用建造者模式。

2. 多个部件或零件,都可以装配到一个对象中,但是产生的运行结果又不相同时,则可以使用该模式。

3. 产品类非常复杂,或者产品类中的调用顺序不同产生了不同的效能,这里使用建造者模式非常合适

4. 在对象创建过程中会使用到系统 中的一些其他对象,这些对象在产品对象的创建过程中不易得到时,也可以采用建造者模式封装该对象的创建过程。这种场景只能是一个补偿方法,因为一个对象不容易获得,在设计阶段没有发现,而要通过创建者模式柔化创建过程,本身已经违反设计的最初目标。

五、建造者模式的注意事项

建造者关注的是零件类型和装配工艺(顺序),这是它与工厂方法模式最大不同的地方,虽然同为创建类模式,但是点不同。














原创粉丝点击