JAVA设计模式之建造者模式

来源:互联网 发布:软件日记 编辑:程序博客网 时间:2024/06/06 03:19


一、 建造者模式的定义

    建造者模式也叫生成器模式 : 将一个复杂的对象的构建与它的表示分离,使得同样的构建过程可以创建不同的表示。

    在构建者中有4个角色 : 

    1、 Product 产品类

      通常是实现模板方法模式,就是有模板方法(主方法)、基本方法。      

public class Product {  public void doSomething(){  //独立业务处理  }}

    2、 Builder 抽象建造者

      规范产品的组建,一般是由子类实现。

public abstract class Builder {  //设置产品的不同部分,以获得不同的产品  public abstract void setPart();  //建造产品  public abstract Product buildProduct();}

    3、 ConcreteBuilder 具体建造者

      实现凑响雷定义的所有方法,并且返回一个组建好的对象。

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

    4、 Director 导演类

      负责安排已有模块的顺序,然后告诉 Builder 开始建造。

public class Director {  private Builder builder = new ConcreteProduct();  //构建不同的产品  public Product getAProduct(){  builder.setPart();  /*  * 设置不同的零件,产生不同的产品  */  return builder.buildProduct();  }}

二、 建造者模式的优点

    1、封装性

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

    3、便于控制细节风险

三、 建造者模式的使用场景

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

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

    3、产品类非常复杂,或者产品类中的调用顺序不同产生了不同的效能,这个时候使用建造者模式是非常适合。

    4、在对象创建过程中会使用到系统中的一些其他对象,这些对象在产品对象的创建过程中不易得到时,也可以采用建造者模式封装该对象的创建过程。

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

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

  

实战 : 

车辆模型的抽象类

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")){//如果是engine boom关键this.engineBoom(); //引擎开始轰鸣}}}//把传递过来的值传递到类内final public void setSequence(ArrayList sequence){this.sequence = sequence;}}

奔驰模型代码


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

宝马模型代码

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


奔驰模型运行

public class Client {public static void main(String[] args) {/** 客户告诉XX公司,我要这样一个模型,然后XX公司就告诉我老大* 说要这样一个模型,这样一个顺序,然后我就来制造*/BenzModel benz = new BenzModel();//存放run的顺序ArrayList<String> sequence = new ArrayList<String>();sequence.add("engine boom"); //客户要求,run的时候先发动引擎sequence.add("start"); //启动起来sequence.add("stop");//开了一段就停下来//我们把这个顺序赋予奔驰车benz.setSequence(sequence);benz.run();}}

运行结果如下所示:
奔驰车的引擎是这个声音的...
奔驰车跑起来是这个样子的...
奔驰车应该这样停车...


到这里可以很好的运行,但是还有一个问题 : 我们现在只运行了一辆如果是N辆车呢? 是不是就特别麻烦而且代码的重复性特别高 既然有问题我们就解决它


抽象汽车组装者

package com.example.liangshaoteng.myapplication.shejimoshizicandao.danyizhizhe.jianzhaozhe;import java.util.ArrayList;/** * Created by liangshaoteng on 17-7-21. */public abstract class CarBuilder {    public abstract void setSequence(ArrayList<String> sequence);    public abstract carModel getCarModel();}

奔驰车

package com.example.liangshaoteng.myapplication.shejimoshizicandao.danyizhizhe.jianzhaozhe;import java.util.ArrayList;/** * Created by liangshaoteng on 17-7-24. */public class BenzBuilder extends CarBuilder {    private BenzModel benzModel = new BenzModel();    @Override    public void setSequence(ArrayList<String> sequence) {        this.benzModel.setSequence(sequence);    }    @Override    public carModel getCarModel() {        return this.benzModel;    }}

宝马车

package com.example.liangshaoteng.myapplication.shejimoshizicandao.danyizhizhe.jianzhaozhe;import java.util.ArrayList;/** * Created by liangshaoteng on 17-7-24. */public class BMWBuilder extends CarBuilder {    private BMWModel bmw = new BMWModel();    public carModel getCarModel() {        return this.bmw;    }    public void setSequence(ArrayList<String> sequence) {        this.bmw.setSequence(sequence);    }}

public class Client {public static void main(String[] args) {  //存放run的顺序  ArrayList<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.getCarModel();  //奔驰车跑一下看看  benz.run();  }}


运行结果如下所示:
奔驰车的引擎是这个声音的...
奔驰车跑起来是这个样子的...
奔驰车应该这样停车...


以上博客根据设计模式之禅来写的,在这里特别感谢作者 : 秦小波