JAVA设计模式之建造者模式


一、 建造者模式的定义

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

    在构建者中有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();
  }
}


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


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

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值