返回路径:咖啡价格=牛奶+咖啡价格=巧克力+牛奶咖啡价格 } } }

时间:2022-02-07 03:23:08

装饰者模式 问题场景

如果要计算一杯咖啡的价格,只需要挪用其获取价格的要领就可以了,,但是如果需要加一些质料,好比牛奶、巧克力、糖等等,这些质料也必需返回它们价格以便于用于汇总计算,但是质料有很多,我们并不能事先预测买家需要哪些质料,所以似乎只能在咖啡类中做出判定去确认买家需要的质料后才华计算出功效,但这并不是一个好的解决思路,由于质料可能有上100种,我们不成能写100次判断去确认加的是哪些质料,况且此后有新进的质料,还得继续多处改削代码。解决方法是使用抽象类和包装器,抽象类供给可重写的获取价格的要领,由饮料子类去实现自身的价格,而质料也可以从同一个抽象类派生,这样,饮料类只需要返回自身的价格,而质料类则依赖于抽象类的实现(饮料类),挪用抽象类的获取价格的要领并加上质料自身的价格就可以在外部挪用质料时计算出总价格。

总结模式

在不窜改类型布局的情况下,只操作现有代码为类型附加其它的成果。装饰者也叫包装器,包装器需要依赖一个抽象类的具体实现类,以便挪用依赖东西的要领获取功效。

代码示例

namespace AppCUI
{
    //超类
    public abstract class Drink
    {
        public abstract double GetPrice( );
    }

    //具体的饮料
    public class Coffe : Drink
    {
        //返回自身的价格
        public override double GetPrice( )
        {
            return 12.5;
        }
    }

    //具体的质料也从饮料派生,以便重写价格
    public class Milk : Drink
    {
        //饮料的价格需要附加我的价格,所以我需要得到饮料,以便计算总价格
        private Drink drink;

        //饮料抽象的具体类通过结构函数注入给我
        public Milk( Drink drink )
        {
            this.drink = drink;
        }

        //计算总价格
        public override double GetPrice( )
        {
            return 1.2 + drink.GetPrice( );
        }
    }

    public class Chocolate : Drink
    {
        private Drink drink;

        public Chocolate( Drink drink )
        {
            this.drink = drink;
        }

        public override double GetPrice( )
        {
            return 1.5 + drink.GetPrice( );
        }
    }

    public class Programe
    {
        static void Main( string[] args )
        {
            Drink drink = new Coffe( ); //我要一杯咖啡
            drink = new Milk( drink ); //咖啡需要加牛奶
            drink = new Chocolate( drink ); //牛奶咖啡需要加糖
            Console.WriteLine( drink.GetPrice( ) ); //巧克力内部维护了牛奶咖啡的价格,牛奶维护了咖啡的价格,返回路径:咖啡价格=>牛奶+咖啡价格=>巧克力+牛奶咖啡价格
        }
    }
}