定义

装饰者模式以对客户透明的方式动态地给一个对象附加上更多的责任,装饰者模式相比生成子类可以更灵活地增加功能。

  • Component抽象构件
          Component是一个接口或者是抽象类,就是定义我们最核心的对象,也就是最原始的对象。 
  • ConcreteComponent具体构件
          ConcreteComponent是最核心,最原始,最基本的接口和或抽象类的实现,你要装饰的就是它。 
  • Decorator装饰角色
         一般是一个抽象类,实现接口或者抽象方法,它里面可不一定有抽象的方法,在它的属性里必然有一个private变量指向Component抽象构件。 
  • 具体装饰角色
          ConcreteDecoratorA和ConcreteDecoratorB是两个具体的装饰类。
 
具体代码如下:
namespace ConsoleApplication1
{
    /// <summary>
    /// 抽象构件
    /// </summary>
    public abstract class Component
    {
        public abstract void operate();
    }
    /// <summary>
    /// 具体构件
    /// </summary>
    public class ConcreteComponent : Component
    {
        public override void operate()
        {
            Console.WriteLine("do something");
        }
    }
    /// <summary>
    /// 抽象装饰者
    /// </summary>
    public abstract class Decorator : Component
    {
        private Component component = null;
        public Decorator(Component _component)
        {
            this.component = _component;
        }
        public override void operate()
        {
            this.component.operate();
        }
    }
    /// <summary>
    /// 具体的装饰者
    /// </summary>
    public class ConcreteDecoratorA : Decorator
    {
        public ConcreteDecoratorA(Component _component)
            : base(_component)
        {
        }
        //定义自己的修饰方法
        private void methodA()
        {
            Console.WriteLine("methodA 修饰");
        }
        //重写父类的operate方法
        public override void operate()
        {
            this.methodA();
            base.operate();
        }
    }
    /// <summary>
    /// 具体的装饰者
    /// </summary>
    public class ConcreteDecoratorB : Decorator
    {
        public ConcreteDecoratorB(Component _component)
            : base(_component)
        {
        }
        //定义自己的修饰方法
        private void methodB()
        {
            Console.WriteLine("methodB 修饰");
        }
        //重写父类的operate方法
        public override void operate()
        {
            base.operate();
            this.methodB();
        }
    }
    class Program
    {
        static void Main(string[] args)
        {
            Component component = new ConcreteComponent();
            //第一次修饰
            component = new ConcreteDecoratorA(component);
            //第二次修饰
            component = new ConcreteDecoratorB(component);
            component.operate();
            Console.ReadLine();
        }
    }
}
View Code

 

装饰者模式的优缺点

看完装饰者模式的详细介绍之后,我们继续分析下它的优缺点。

优点:

  1. 装饰这模式和继承的目的都是扩展对象的功能,但装饰者模式比继承更灵活
  2. 通过使用不同的具体装饰类以及这些类的排列组合,设计师可以创造出很多不同行为的组合
  3. 装饰者模式有很好地可扩展性

缺点:装饰者模式会导致设计中出现许多小对象,如果过度使用,会让程序变的更复杂。并且更多的对象会是的差错变得困难,特别是这些对象看上去都很像。

使用场景

下面让我们看看装饰者模式具体在哪些情况下使用,在以下情况下应当使用装饰者模式:

    1. 需要扩展一个类的功能或给一个类增加附加责任。
    2. 需要动态地给一个对象增加功能,这些功能可以再动态地撤销。
    3. 需要增加由一些基本功能的排列组合而产生的非常大量的功能