简单理解建造者模式
建造者模式(Builder Pattern)使用多个简单的对象一步一步构建成一个复杂的对象。它允许用户只通过指定复杂对象的类型和内容就可以构建它们,用户不需要知道内部的具体构建细节。
这个模式适用于:某个对象的构建过程复杂的情况下使用
结构
- Product: 产品类所描述的是我们最终想要的到的结果统称
- Builder: 建造者的接口定义,他定义了建造某种产品类需要的步骤,但不提供实现
- ConcreteBuilder: 建造者的实现类,继承自 Builder 提供一种创建类型的具体步骤,是我们封装的拓展对象
- Director: Builder 类的创建者,由他来为各种 Builder 来赋值属性,Director隔离了建造者实现类与实际客户端创建,让实际对象的创建只关注于对象的属性。
使用场景
- 产品对象内部具有复杂的结构,产品对象包含多个成员属性,适用建造者模式可以隔离复杂对象的创建和适用,并使得相同的 创建过程可以创建不同的对象
- 相同的方法,不同的执行顺序,产生不同的事件结果时
简单实现
建造者模式可以用于描述KFC如何创建套餐:套餐是一个复杂对象,它一般包含主食(如汉堡、鸡肉卷等)和饮料(如果汁、可乐等)等组成部分,不同的套餐有不同的组成部分,而KFC的服务员可以根据顾客的要求,一步一步装配这些组成部分,构造一份完整的套餐,然后返回给顾客。
实体类
主食和饮料
public class Food {
private String name;
public Food(String name) {
this.name = name;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
}
public class Drink {
private String name;
public Drink(String name) {
this.name = name;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
}
Product
套餐
public class Meal {
private Food food;
private Drink drink;
public Food getFood() {
return food;
}
public void setFood(Food food) {
this.food = food;
}
public Drink getDrink() {
return drink;
}
public void setDrink(Drink drink) {
this.drink = drink;
}
}
Builder
抽象建造者
public abstract class MealBuilder {
Meal meal = new Meal();
public abstract void buildeFood();
public abstract void buildeDrink();
public Meal getMeal(){
return meal;
}
}
ConcreteBuilder
具体建造者:套餐A、套餐B
public class MealABuilder extends MealBuilder{
@Override
public void buildeFood() {
meal.setFood(new Food("汉堡"));
}
@Override
public void buildeDrink() {
meal.setDrink(new Drink("可乐"));
}
}
public class MealBBuilder extends MealBuilder{
@Override
public void buildeFood() {
meal.setFood(new Food("鸡肉卷"));
}
@Override
public void buildeDrink() {
meal.setDrink(new Drink("芬达"));
}
}
Director
服务员
public class Waiter {
public void command(MealBuilder mealBuilder){
mealBuilder.buildeFood();
mealBuilder.buildeDrink();
}
}
测试
public class Client {
public static void main(String[] args) {
MealBuilder mealBuilder = new MealABuilder();
Waiter waiter = new Waiter();
waiter.command(mealBuilder);
Meal meal = mealBuilder.getMeal();
System.out.println("套餐A:");
System.out.println(meal.getFood().getName());
System.out.println(meal.getDrink().getName());
mealBuilder = new MealBBuilder();
waiter.command(mealBuilder);
meal = mealBuilder.getMeal();
System.out.println("套餐B:");
System.out.println(meal.getFood().getName());
System.out.println(meal.getDrink().getName());
}
}
结果
套餐A:
汉堡
可乐
套餐B:
鸡肉卷
芬达
建造者模式的优缺点
优点:
- 分离了对象子组件的单独构造(由Builder来负责)和装配(由Director负责)。从而可以构造出复杂的对象。
- 每一个具体建造者都相对独立,而与其他的具体建造者无关,因此可以很方便地替换具体建造者或增加新的具体建造者, 用户使用不同的具体建造者即可得到不同的产品对象 。
- 实现了构建算法、装配算法的解耦,实现了更好的复用
缺点:
- 产品必须有共同点,范围有限制。
- 如内部变化复杂,会有很多的建造类。