• 建造者模式


            今天我们讨论一下 Builder 建造者模式,这个 Builder,其实和模板模式非常的像,但是也有区别,那就是在模板模式中父类对子类中的实现进行操作,在父类之中进行一件事情的处理,但是在 Builder 模式之中,父类和子类都不用关心怎么处理,而是用另一个类来完成对这些方法的有机组合,这个类的职责就是监工,规定了到底要怎么样有机的组合这些方法。在监工类(Director)中,将父类组合进去,然后调用父类的操作来抽象的实现一件事情,这就是面向接口(抽象)变成的妙处了,当然这个 Builder 可以使接口也可以是抽象类,在这里我们使用抽象类。

    目录

    1.UML图

    2.案例

     3. 小结


     


     

    1.UML图

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

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

    如何解决:将变与不变分离开。

    关键代码:建造者:创建和提供实例,导演:管理建造出来的实例的依赖关系。

    2.案例

            一个快餐店的商业案例,其中,一个典型的套餐可以是一个汉堡(Burger)和一杯冷饮(Cold drink)还有小吃(Snack)。汉堡(Burger)可以是素食汉堡(Veg Burger)或鸡肉汉堡(Chicken Burger),它们是包在纸盒(Wrapper)中。冷饮(Cold drink)可以是可口可乐(coke)或百事可乐(pepsi),它们是装在瓶子(bottle)中,小吃有(FrenchFrice),蛋挞(EggTart)。

            我们将创建一个表示食物条目(比如汉堡和冷饮、小吃)的 Item 接口和实现 Item 接口的实体类,以及一个表示食物包装的 Packing 接口和实现 Packing 接口的实体类,汉堡是包在纸盒中,冷饮是装在瓶子中,小吃也是盒装。

    然后我们创建一个 Meal 类,带有 Item 的 List 和一个通过结合 Item 来创建不同类型的 Meal 对象的 MealBuilder我构建了两种Meal类型,作为构造者,你可以使用不同组合构建更多Meal。

     Item类:

    1. internal abstract class Item
    2. {
    3. public string Name { get; set; }
    4. public float Price { get; set; }
    5. public IPack? Package { get; set; }
    6. public void SetPrice(float p)=>Price = p;
    7. }

    IPack接口:

    1. public interface IPack
    2. {
    3. public string Pack();
    4. }

    三种包装:

    1. internal class Bottle : IPack
    2. {
    3. public string Pack()
    4. {
    5. return "Bottle";
    6. }
    7. }
    8. internal class PlasticBag:IPack
    9. {
    10. public string Pack() => "PlasticBag";
    11. }
    12. internal class Wrapper:IPack
    13. {
    14. public string Pack()
    15. {
    16. return "Wrapper ";
    17. }
    18. }

    饮料抽象类:

    1. internal class Coke:ColdDrink
    2. {
    3. public Coke()
    4. {
    5. Price = 5.0f;
    6. Name = "Coke";
    7. }
    8. }

    两种冷饮:

    1. internal class Coke:ColdDrink
    2. {
    3. public Coke()
    4. {
    5. Price = 5.0f;
    6. Name = "Coke";
    7. }
    8. }
    9. internal class Pepsi:ColdDrink
    10. {
    11. public Pepsi()
    12. {
    13. Name = "Pepsi";
    14. Price = 6.0f;
    15. }
    16. }

    小吃抽象类:

    1. internal abstract class Snack : Item
    2. {
    3. public Snack() => Package = new Wrapper();
    4. }

    两种小吃:

    1. internal class EggTart:Snack
    2. {
    3. public EggTart()
    4. {
    5. Price = 9.99f;
    6. Name = "Egg Tart";
    7. }
    8. }
    9. internal class FrenchFrice:Snack
    10. {
    11. public FrenchFrice()
    12. {
    13. Price = 12.0f;
    14. Name = "French Frice";
    15. }
    16. }

    汉堡和小吃类似,就不贴了,然后是Meal:

    1. internal class Meal
    2. {
    3. private List Items { get; } = new List();
    4. public void AddItem(Item item)=>Items.Add(item);
    5. public float GetCost()
    6. {
    7. Console.WriteLine("**********************COST************************");
    8. return Items.Aggregate(0f, (sum, item) => item.Price + sum);
    9. }
    10. public void ShowItems()
    11. {
    12. Console.WriteLine("--------------------------List-----------------------");
    13. Items.ForEach(item =>
    14. {
    15. Console.WriteLine($"Item: {item.Name} \n\t packing: {item.Package?.Pack()}" +
    16. $"\t\n price: {item.Price}");
    17. });
    18. }
    19. }

    构造者MealBuilder:

    1. internal class MealBuilder
    2. {
    3. public Meal PrepareVegMeal()
    4. {
    5. Meal meal = new Meal();
    6. meal.AddItem(new VegBurger());
    7. meal.AddItem(new Coke());
    8. meal.AddItem(new FrenchFrice());
    9. return meal;
    10. }
    11. public Meal PrepareNonVegMeal()
    12. {
    13. Meal meal = new Meal();
    14. meal.AddItem(new ChickenBurger());
    15. meal.AddItem(new Pepsi());
    16. meal.AddItem(new EggTart());
    17. return meal;
    18. }
    19. }

     3. 小结

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

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

    使用场景: 1、需要生成的对象具有复杂的内部结构。 2、需要生成的对象内部属性本身相互依赖。

    注意事项:与工厂模式的区别是:建造者模式更加关注与零件装配的顺序。


    完整代码:DesignPatternReview

  • 相关阅读:
    Java中的this关键字
    linux之管道符详解
    vue3子页面刷新,v-show联合v-if实现柱状图隐藏展示,和按条件查询
    手把手带你实现JAVA自定义异常和全局异常处理
    【基站维修工程师】python实现-附ChatGPT解析
    人大金仓Windows下可以使用计划任务吗?创建完没有反应?
    语音识别准确率的计算:CER
    Could not read from boot medium. System halted.
    前端开发学习之【AJAX】
    谁家的加密密钥,写死在代码里?(说的就是你)
  • 原文地址:https://blog.csdn.net/q__y__L/article/details/126325185