定义:
建造者模式(Builder Pattern)也叫做生成器模式,是将一个复杂对象的构建与它的表示分离,使得同样的构建过程可以创建不同的表示。简单的说就是对于复杂对象或者方法的调用逻辑的封装交易给建造者处理,客户端调用只需要提供调用要求,而不是考虑实现细节。
基本模型:
从类图中可以看出基本的建造者模式共有四个角色。:
Product 产品类:包含产品信息
Builder 抽象建造者类:抽取建造者类公共方法
ConcreteBuilder 实际建造者类:实现Builder的方法,返回一个组件好的对象
Director 导演类: 负责安排已有模块的顺序,然后告诉Builder开始建造,在上面的例子中就是我们的老大,××公司找到老大,说我要这个或那个类型的车辆模型,然后老大就把命令传递给我,我和我的团队就开始拼命地建造,于是一个项目建设完毕了。
举例说明:
需求:小明为了感谢帮调bug的大熊去咖啡店帮同事买咖啡,小明想喝美式,大熊要喝拿铁。
设计思路:美式和拿铁都是咖啡是产品类,咖啡机最终调制咖啡也就是建设者,不过店员是来控制是不不加糖,加奶,所以是导演类。
最终实现:
package com.builder;
import java.util.List;
/**
* 咖啡
*/
public class Coffee {
private void addMike() {
System.out.println("加牛奶");
}
private void addSugar() {
System.out.println("加糖");
}
private void addIce() {
System.out.println("加冰");
}
private void groundCoffeeBean() {
System.out.println("加研磨好的咖啡");
}
private void addWater() {
System.out.println("冲水");
}
//咖啡的组成
public void part(List<String> list) {
for (int i = 0; i < list.size(); i++) {
if ("加研磨好的咖啡".endsWith(list.get(i))) {
this.groundCoffeeBean();
} else if ("冲水".endsWith(list.get(i))) {
this.addWater();
} else if ("加牛奶".endsWith(list.get(i))) {
this.addMike();
} else if ("加糖".endsWith(list.get(i))) {
this.addSugar();
} else if ("加冰".endsWith(list.get(i))) {
this.addIce();
}
}
}
}
package com.builder;
import java.util.List;
/**
* 咖啡机
*/
public abstract class CoffeeMachine {
//制作咖啡
public abstract Coffee makeCoffee(List<String> sequence);
}
package com.builder;
import java.util.List;
/**
* 智能咖啡机
*/
public class AiCoffeeMachine extends CoffeeMachine{
private Coffee coffee = new Coffee();
@Override
public Coffee makeCoffee(List<String> sequence) {
coffee.part(sequence);
return coffee;
}
}
package com.builder;
import java.util.ArrayList;
import java.util.List;
/**
* 店员
* Director类
*/
public class Clerk {
private List<String> list = null;
private AiCoffeeMachine ac = new AiCoffeeMachine();
/**
* 制作冰美式
* @return
*/
public Coffee getCafeAmericano(){
System.out.println("开始制作冰美式----");
list = new ArrayList<>();
list.add("加研磨好的咖啡");
list.add("冲水");
list.add("加冰");
Coffee coffee = ac.makeCoffee(list);
System.out.println("冰美式制作完成----");
return coffee;
}
/**
* 制作拿铁
* @return
*/
public Coffee getLatte(){
System.out.println("开始制作拿铁----");
list = new ArrayList<>();
list.add("加研磨好的咖啡");
list.add("冲水");
list.add("加牛奶");
list.add("加糖");
Coffee coffee = ac.makeCoffee(list);
System.out.println("拿铁制作完成----");
return coffee;
}
}
package com.builder;
public class Test {
public static void main(String[] args) {
Clerk clerk = new Clerk();
clerk.getCafeAmericano();
clerk.getLatte();
}
}
打印结构:
开始制作冰美式----
加研磨好的咖啡
冲水
加冰
冰美式制作完成----
开始制作拿铁----
加研磨好的咖啡
冲水
加牛奶
加糖
拿铁制作完成----
总结:
建造者模式的优点:
封装性良好,客户端的调用并不关心具体实现细节
易于扩展,建造者是独立的,如果哪天需要生产奶茶,那扩展一个奶茶建造者。
与模板方法模式和工厂模式:
与模板方法模式:在商品角色中可以与模板方法模式配合使用,建造者模式更关注对象的具体实现细节
与工厂模式:两种模式的关注点和职责不一致,工厂模式的职则是生产对象,并不关系零件的组装顺序,而建造者模式关注的零件的组装顺序,零件的组装顺序不同,生成的对象可能也不同。