一、 建造者模式的定义
建造者模式也叫生成器模式 : 将一个复杂的对象的构建与它的表示分离,使得同样的构建过程可以创建不同的表示。
在构建者中有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();
}
}
运行结果如下所示:
奔驰车的引擎是这个声音的...
奔驰车跑起来是这个样子的...
奔驰车应该这样停车...
以上博客根据设计模式之禅来写的,在这里特别感谢作者 : 秦小波