C#设计模式——装饰模式

装饰模式:

她是什么?
装饰模式是为已有功能动态添加功能的一种方式。

为什么要有装饰模式?她能解决什么问题?
添加功能时,装饰模式扩展功能比生成子类更加灵活,避免“子类爆炸”。怎么个灵活法,大家且往下看。

她是怎么做的?
把每个要装饰的功能在单独的类中,并让这个类包装它所要装饰的对象,因此,当需要执行特殊行为时,客户代码就可以在运行时根据需要有选择的按顺序使用装饰功能包装对象了。就像穿衣服,从里到外一层层穿,一层层包装,按照顺序依次做到的。

效果如何,还要看穿衣的主人?
每个装饰对象的实现就和如何使用这个对象分离开了,每个装饰对象只关心自己的功能,不需要关心如何被添加到对象链中,这样是不是很省心啊?

优点:
  • 把类中的装饰功能从类中搬移去除,这样可以简化原有的类。
  • 有效将类的核心职责和装饰功能区分开了。而且可以去除相关类中重复的装饰职责。
装饰模式结构图:
C#设计模式——装饰模式_第1张图片

小例子: 某天我来到一家饮料店,我想要各种口味的饮料。那么用装饰模式如何来实现代码?
首先想到饮料可以抽象出一个类,涉及到口味,所以根据添加的佐料不同,也该抽象出类,每种佐料抽象出一个类。

代码展示:
    
//饮料的抽象类
    abstract class Beverage
    {
        protected string Description = "Unknown Beverage";
        public virtual string GetDescription()
        {
            return Description;
        }
        public abstract double Cost();
    }
    //具体饮料类
    class Coffee : Beverage
    {
        public Coffee()
        {
            Description="coffee";
        }
        public override double Cost()
        {
            return 1.99;
        }
    }
    //装饰器抽象类
    abstract class CondimentDecorator : Beverage
    {
        protected Beverage Beverage;
        public override abstract string GetDescription();
    }
    //两个具体的装饰器
    class Milk : CondimentDecorator 
    {
        public Milk(Beverage beverage)
        {
            this.Beverage = beverage;
        }
        public override string GetDescription()
        {
            return "Milk" + Beverage.GetDescription();
        }
        public override double Cost()
        {
            return .10 + Beverage.Cost();
        }
    }
    class Mocha : CondimentDecorator 
    {
        public Mocha(Beverage beverage)
        {
            this.Beverage = beverage;
        }
        public override string GetDescription()
        {
            return "Mocha" + Beverage.GetDescription();
        }
        public double Cost()
        {
            return .20 + Beverage.Cost();
        }
    }
    //现在顾客可以任意选佐料了
    class Program
    {
        static void Main(string[] args)
        {
            //来杯咖啡
            Beverage beverage = new Coffee();
            Console.WriteLine(beverage.GetDescription()+"$"+beverage.Cost());
            //来杯摩卡咖啡
            Beverage mocha = new Mocha(beverage);
            Console.WriteLine(mocha.GetDescription()+": $"+mocha.Cost ());
            //来杯咖啡牛奶
            Beverage mochaMilk = new Milk(mocha);
            Console.WriteLine(mochaMilk.GetDescription()+":$"+mochaMilk.Cost());
            Console.ReadKey();
        }
    }

总结:
根据以上例子的实现,想要原味咖啡就有原味的,想要摩卡咖啡就有摩卡咖啡,如果在想要别的口味了,我们只需要在代码中添加功能(继承CondimentDecorator一个类),然后修改客户端代码即可,所以我们知道了装饰模式可以很灵活的动态的添加用户想要的功能,这个想必大家都喜欢。
谢谢大家的阅读!


你可能感兴趣的:(【设计模式】)