建造者模式

        今天我们讨论一下 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类:

    internal abstract class Item
    {
        public string Name { get; set; }
        public float Price { get; set; }
        public IPack? Package { get; set; }
        public void SetPrice(float p)=>Price = p;
    }

IPack接口:

    public interface IPack
    {
        public string Pack();
    }

三种包装:

    internal class Bottle : IPack
    {
        public string Pack()
        {
            return "Bottle";
        }
    }

    internal class PlasticBag:IPack
    {
        public string Pack() => "PlasticBag";
    }



    internal class Wrapper:IPack
    {
        public string Pack()
        {
            return "Wrapper ";
        }
    }

饮料抽象类:

    internal class Coke:ColdDrink
    {
        public Coke()
        {
            Price = 5.0f;
            Name = "Coke";
        }
    }

两种冷饮:

    internal class Coke:ColdDrink
    {
        public Coke()
        {
            Price = 5.0f;
            Name = "Coke";
        }
    }


    internal class Pepsi:ColdDrink
    {
        public Pepsi()
        {
            Name = "Pepsi";
            Price = 6.0f;
        }
    }

小吃抽象类:

    internal abstract class Snack : Item
    {
        public Snack() => Package = new Wrapper();
    }

两种小吃:

    internal class EggTart:Snack
    {
        public EggTart()
        {
            Price = 9.99f;
            Name = "Egg Tart";
        }
    }


    internal class FrenchFrice:Snack
    {
        public FrenchFrice()
        {
            Price = 12.0f;
            Name = "French Frice";
        }
    }

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

internal class Meal
    {
        private List<Item> Items { get; } = new List<Item>();
        public void AddItem(Item item)=>Items.Add(item);

        public float GetCost()
        {
            Console.WriteLine("**********************COST************************");
            return Items.Aggregate(0f, (sum, item) => item.Price + sum);
        }
        
        public void  ShowItems()
        {
            Console.WriteLine("--------------------------List-----------------------");
            Items.ForEach(item =>
            {
                Console.WriteLine($"Item: {item.Name} \n\t packing: {item.Package?.Pack()}" +
                    $"\t\n  price:  {item.Price}");
            });
        }
    }

构造者MealBuilder:

    internal class MealBuilder
    {
        public Meal PrepareVegMeal()
        {
            Meal meal = new Meal();
            meal.AddItem(new VegBurger());
            meal.AddItem(new Coke());
            meal.AddItem(new FrenchFrice());
            return meal;
        }
        public Meal PrepareNonVegMeal()
        {
            Meal meal = new Meal();
            meal.AddItem(new ChickenBurger());
            meal.AddItem(new Pepsi());
            meal.AddItem(new EggTart());
            return meal;
        }
    }

 3. 小结

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

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

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

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


完整代码:DesignPatternReview

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值