Java建造者模式

x33g5p2x  于2021-10-01 转载在 Java  
字(3.5k)|赞(0)|评价(0)|浏览(396)

介绍

主要解决: 主要解决在软件系统中,有时候面临着"一个复杂对象"的创建工作,其通常由各个部分的子对象用一定的算法构成;由于需求的变化,这个复杂对象的各个部分经常面临着剧烈的变化,但是将它们组合在一起的算法却相对稳定。

何时使用: 一些基本部件不会变,而其组合经常变化的时候。

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

优点: 1、建造者独立,易扩展。 2、便于控制细节风险。

缺点: 1、产品必须有共同点,范围有限制。 2、如内部变化复杂,会有很多的建造类。

使用场景: 比如买手机的手机套餐 买衣服的组合套餐 比如外卖的组合套餐 …

注意事项: 建造者模式更加关注 零件装配。

实现

我们假设一个快餐店的商业案例,其中,一个典型的套餐可以是一个汉堡(Burger)和一杯冷饮(Cold drink)。

汉堡(Burger)可以是素食汉堡(Veg Burger)或鸡肉汉堡(Chicken Burger),它们是包在纸盒中。

冷饮(Cold drink)可以是可口可乐(coke)或百事可乐(pepsi),它们是装在瓶子中。

我们将创建一个商品条目 接口 Item和实现 Item 接口的实体类,以及一个表示食物包装的 Packing 接口和实现 Packing 接口的实体类,

汉堡是包在纸盒中,冷饮是装在瓶子中。

然后我们创建一个 Meal(套餐) 类,内含带有 ItemArrayList 和套餐生产类 MealBuilder

通过BuilderPatternDemo(测试类) 来演示类使用 MealBuilder 来创建一个 Meal(套餐)。

现在看不懂上面这图没关系 当将下面案例弄懂了 在回来看这张图 你就能看懂了

商品接口 Item

public interface Item {
    String name();  //商品名称
    Packing packing(); //商品包装
    float price();//商品价格
}

因为包装是固定的 那么我们可以提取出来 放入抽象类中实现

而价格和商品不是固定的我们可以通过不同的子类来实现

这样有助于代码的扩展和代码的复用以及减少代码的冗余

汉堡抽象类 Burger

//汉堡
public abstract class Burger implements Item {
    //实现汉堡包装
    @Override
    public Packing packing() {
        return new Wrapper();
    }
}

鸡肉汉堡包的实现类 ChickenBurger

//鸡肉汉堡
public class ChickenBurger extends Burger {
    //汉堡价格
    @Override
    public float price() {
        return 50.5f;
    }
    //名称
    @Override
    public String name() {
        return "鸡肉汉堡包";
    }
}

蔬菜汉堡的实现类 VegBurger

//蔬菜汉堡
public class VegBurger extends Burger {

    //价格
    @Override
    public float price() {
        return 25.0f;
    }
    //名称
    @Override
    public String name() {
        return "蔬菜汉堡";
    }
}

冷饮抽象类ColdDrink

//冷饮
public abstract class ColdDrink implements Item {
    //实现冷饮包装
    @Override
    public Packing packing() {
        return new Bottle();
    }

}

口可口乐 Coke

//口可口乐
public class Coke extends ColdDrink {
    //价格
    @Override
    public float price() {
        return 30.0f;
    }
    //名称
    @Override
    public String name() {
        return "可口可乐";
    }
}

百事可乐Pepsi

//百事可乐
public class Pepsi extends ColdDrink {
    //价格
    @Override
    public float price() {
        return 35.0f;
    }
    //名称
    @Override
    public String name() {
        return "百事可乐";
    }
}

包装接口Packing

public interface Packing {
     String pack();//包装
}

瓶装Bottle

public class Bottle implements Packing {
    @Override
    public String pack() {
        return "瓶装";
    }
}

盒包装纸Wrapper

public class Wrapper implements Packing {

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

套餐 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.println("{ 商品名称:"+item.name()+", 包装:"+item.packing().pack()+", 价格 : "+item.price()+"}");
        }
    }
}

有了套餐类 我们就可以 生产套餐到 List<Item>中

生产套餐MealBuilder

//生产套餐
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;
    }
}

测试BuilderPatternDemo

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

        Meal vegMeal = mealBuilder.prepareVegMeal();
        System.out.println("---------------素食套餐----------------");
        vegMeal.showItems();
        System.out.println("总价格: " +vegMeal.getCost());

        Meal nonVegMeal = mealBuilder.prepareNonVegMeal();
        System.out.println("\n\n----------------------非素食套餐----------------------");
        nonVegMeal.showItems();
        System.out.println("总价格: " +nonVegMeal.getCost());
    }
}

---------------素食----------------
商品 : {蔬菜汉堡包装 : 包装纸, 价格 : 25.0}
商品 : {可口可乐包装 : 瓶装, 价格 : 30.0}
总价格: 55.0

----------------------非素食----------------------
商品 : {鸡肉汉堡包包装 : 包装纸, 价格 : 50.5}
商品 : {百事可乐包装 : 瓶装, 价格 : 35.0}
总价格: 85.5

相关文章

最新文章

更多