建造者模式(Builder Pattern)使用多个简单的对象一步一步构建成一个复杂的对象。这种类型的设计模式属于创建型模式。有一些复杂的对象他包含的基本部件不会变,而基本部件组合经常变化的时候,就可以使用建造者模式。
常用的是Builder的链式调用,demo:
public class Meal {
private boolean eatRice;
private boolean eatFish;
public Meal() {
this(new Builder());
}
// 给参数赋值
public Meal(Builder builder) {
this.eatRice = builder.eatRice;
this.eatFish = builder.eatFish;
}
public static class Builder {
boolean eatRice;
boolean eatFish;
// 初始化默认值
public Builder() {
eatRice = true;
eatFish = false;
}
// 设置参数
public Builder eatRice(boolean eatRice) {
this.eatRice = eatRice;
return this;
}
// 设置参数
public Builder eatFish(boolean eatFish) {
this.eatFish = eatFish;
return this;
}
//创建对象并传参
public Meal build() {
return new Meal(this);
}
}
}
调用:
Meal defaultMeal = new Meal();
Meal myMeal = new Meal.Builder().eatRice(false).eatFish(true).build();
不用这种链式调用的方法也是可以的,对于复杂的对象,可以先写好它的每个组件,然后组合起来形成复杂的对象A,对象B…比如肯德基的”套餐”。 下面的例子是:一个快餐店,店中有可口可乐(瓶装)、百事可乐(瓶装)、素食汉堡(袋装)鸡肉汉堡(袋装)可以任意组成套餐,并且以后要方便扩展新的汉堡和饮料。
demo:
定义食物的基本属性接口,和包装接口
// 食物的基本属性
public interface Item {
public String name();
public Packing packing();
public float price();
}
// 包装
public interface Packing {
public String pack();
}
包装的实体类
// 袋装
public class Wrapper implements Packing {
@Override
public String pack() {
return "Wrapper";
}
}
// 瓶装
public class Bottle implements Packing {
@Override
public String pack() {
return "Bottle";
}
}
汉堡和饮料抽象类
// 汉堡
public abstract class Burger implements Item {
@Override
public Packing packing() {
return new Wrapper();
}
@Override
public abstract float price();
}
// 可乐
public abstract class ColdDrink implements Item {
@Override
public Packing packing() {
return new Bottle();
}
@Override
public abstract float price();
}
具体的汉堡
// 蔬菜汉堡
public class VegBurger extends Burger {
@Override
public float price() {
return 25.0f;
}
@Override
public String name() {
return "Veg Burger";
}
}
// 鸡肉汉堡
public class ChickenBurger extends Burger {
@Override
public float price() {
return 50.5f;
}
@Override
public String name() {
return "Chicken Burger";
}
}
具体的饮料
// 可口可乐
public class Coke extends ColdDrink {
@Override
public float price() {
return 30.0f;
}
@Override
public String name() {
return "Coke";
}
}
// 百事可乐
public class Pepsi extends ColdDrink {
@Override
public float price() {
return 35.0f;
}
@Override
public String name() {
return "Pepsi";
}
}
创建套餐的类
public class Meal {
private List<Item> items = new ArrayList<Item>();
public void addItem(Item item){
items.add(item);
}
public float getCost(){
float cost = 0.0f;
for (Item item : items) {
cost += item.price();
}
return cost;
}
public void showItems(){
for (Item item : items) {
System.out.print("Item : "+item.name());
System.out.print(", Packing : "+item.packing().pack());
System.out.println(", Price : "+item.price());
}
}
}
创建我们需要的套餐
public class MealBuilder {
// 蔬菜汉堡可口可乐套餐
public Meal prepareVegMeal (){
Meal meal = new Meal();
meal.addItem(new VegBurger());
meal.addItem(new Coke());
return meal;
}
// 鸡肉汉堡百事可乐套餐
public Meal prepareNonVegMeal (){
Meal meal = new Meal();
meal.addItem(new ChickenBurger());
meal.addItem(new Pepsi());
return meal;
}
// 可以组合任意的套餐
}
调用:
MealBuilder mealBuilder = new MealBuilder();
Meal vegMeal = mealBuilder.prepareVegMeal();
vegMeal.showItems();
建造者模式的优点:
1、建造模式是将复杂的内部创建封装在内部,对于外部调用的人来说,只需知道怎么调用就好了,不需要知道内部的的构建细节,具有良好的封装性。
2、建造者类逻辑独立,易拓展。