【创建型】建造者模式(Builder Pattern)

主要作用:
可以使多个简单的对象,一步一步构建成一个复杂的对象

应用实例:
1、去肯德基,汉堡、可乐、薯条、炸鸡翅等是不变的,而其组合是经常变化的,生成出所谓的"套餐"。 2、JAVA 中的 StringBuilder。

举例:
我们可以假设 我们去饭店:
饭店有沙拉和冷饮。

  • 沙拉可以是素沙拉或者是肉沙拉,他们在放在一次性纸盒里面。
  • 冷饮有胡萝卜汁或者黄瓜汁装在瓶子里面。

我们可以有一个食物菜单,和食物包装类,以及他们的实现。
我们在创建一顿饭需要定哪个菜单,也就是怎么去Builder,之后用这个Builder去创建一顿饭。

1、创建一个菜单和包装接口

/**
 * @description: 创建一个菜单
 */
public interface Item {
    public String name();
    public Packing packing();
    public float price();
}

/**
 * @description: 包装
 */
public interface Packing {
    public String pack();
}

2、实现包装接口,创建瓶子和盒子两个包装

/**
 * @description: 盒子 继承包装Packing
 */
public class PBottle implements Packing {

    @Override
    public String pack() {
        return "瓶子";
    }
}

/**
 * @description: 包装纸 
 */
public class PWrapper implements Packing {

    @Override
    public String pack() {
        return "包装纸";
    }
}

3、实现菜单接口Item,实现基础功能,沙拉+冷饮

/**
 * @description:  沙拉 —— 实现 Item 接口的抽象类
 */
public abstract class Salad implements Item {

    @Override
    public Packing packing() { // 包装  返回   包装纸
        return new PWrapper();
    }

    @Override
    public abstract float price();// 价格
}


/**
 * @description: 冷饮 —— 实现 Item 接口的抽象类
 */
public abstract class LJuice implements Item {

    @Override
    public Packing packing() {
        return new PBottle(); // 盒子 装 冷饮
    }

    @Override
    public abstract float price();
}

4、扩展沙拉+冷饮的类

/**
 * @description: 鸡肉沙拉
 */
public class SLChicken extends Salad {

    @Override
    public float price() {
        return 50.5f;
    }

    @Override
    public String name() {
        return "鸡肉沙拉";
    }
}

/**
 * @description: 素食沙拉
 */
public class SLVeg extends Salad {

    @Override
    public float price() {
        return 25.0f;
    }

    @Override
    public String name() {
        return "素食沙拉";
    }
}


/**
 * @description: 冷饮黄瓜汁
 */
public class LHGJuice extends LJuice {

    @Override
    public float price() {
        return 30.0f;
    }

    @Override
    public String name() {
        return "黄瓜汁";
    }
}

/**
 * @description: 萝卜汁
 */
public class LLBJuice extends LJuice {

    @Override
    public float price() {
        return 35.0f;
    }

    @Override
    public String name() {
        return "萝卜汁";
    }
}

5、在创建一个Meal类,表示为一顿饭

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(", 包装 : "+item.packing().pack());
            System.out.println(", 价格 : "+item.price());
        }
    }
}

6、创建一个Builder,我们要把这一顿饭给 构建出来

/**
 * @description: 创建一个 MealBuilder 类,他就是组装每一顿饭 吃什么的类,可以当作下单
 */
public class MealBuilder {

    /**
     * 素的
     * @return
     */
    public Meal prepareSu (){
        Meal meal = new Meal();
        meal.addItem(new SLVeg());
        meal.addItem(new LHGJuice());
        return meal;
    }

    /**
     * 肉的
     * @return
     */
    public Meal prepareRou (){
        Meal meal = new Meal();
        meal.addItem(new SLChicken());
        meal.addItem(new LLBJuice());
        return meal;
    }
}

最后测试

public class BuilderPatternDemo {
    public static void main(String[] args) {
        MealBuilder mealBuilder = new MealBuilder();

        Meal vegMeal = mealBuilder.prepareSu();
        System.out.println("蔬菜沙拉套餐");
        vegMeal.showItems();
        System.out.println("总额: " +vegMeal.getCost());

        Meal nonVegMeal = mealBuilder.prepareRou();
        System.out.println("\n\n 肉食沙拉套餐");
        nonVegMeal.showItems();
        System.out.println("总额: " +nonVegMeal.getCost());
    }
}

打印:
蔬菜沙拉套餐
Item : 素食沙拉, 包装 : 包装纸, 价格 : 25.0
Item : 黄瓜汁, 包装 : 瓶子, 价格 : 30.0
总额: 55.0


 肉食沙拉套餐
Item : 鸡肉沙拉, 包装 : 包装纸, 价格 : 50.5
Item : 萝卜汁, 包装 : 瓶子, 价格 : 35.0
总额: 85.5
 

基本上就是这些了,总结一下建造者模式就是将一个复杂的构建与其表示相分离,使得同样的构建过程可以创建不同的表示。主要关注与零件装配的顺序。

你可能感兴趣的:(设计模式,java)