第 6 章 —— 装饰模式

6.6 装扮模式总结

    装饰模式把每个要装饰的功能放在单独的类中,并让这个类包装它所要装饰的对象,因此,当需要执行特殊行为时,客户端代码就可以在运行时根据需要有选择地、按顺序地使用装饰功能包装对象了。

    装扮模式是为已有功能动态地添加更多功能的一种方式。

  装饰模式的优点:

    有效地把类的核心职责和装饰功能区分开了(将装饰功能从类中移除,简化了原有的类)。而且可以去除相关类中重复的装饰逻辑(具体的装饰类都继承了抽象装饰类)。

  需要注意的问题:

    装饰模式的顺序很重要,比如加密数据和过滤词汇都可以是数据持久化(存储)以前的装饰功能,但若先加密了数据再用过滤功能就会出问题了,最理想的情况,是保证装饰类之间彼此独立,这样它们就可以以任意的顺序进行组合了。

6.4 装饰模式

    装饰模式动态地给一个对象添加一些额外的职责就增加功能来说,装饰模式比生成子类更为灵活

基本的实现代码:

  Component 类:

      abstract class Component
      {
          public abstract void Operation();
      }

    Component 定义了一个对象接口(抽象类的抽象方法),可以给这些对象动态地添加职责。

  ConcreteComponent 类:

      class ConcreteComponent : Component
      {
          public override void Operation()
          {
              Console.WriteLine("具体对象的操作");
          }
      }

    ConcreteComponent定义了一个具体的对象,也可以给这个对象添加一些职责。

  Decorator 类:(抽象的装饰类,需要继承定义的对象接口)

      abstract class Decorator : Component
      {
          protected Component component;

          public void SetComponent(Component component)       //设置Component
          {
              this.component = component;
          }

          public override void Operation()                    //重写Operation(),实际执行的是Component的Operation()
          {
              if(component != null)
              {
                  component.Operation();
              }
          }
      }

    Decorator,抽象装饰类,继承了 Component,从类外面来扩展 Component 类的功能,但对于 Component 来说,是无需知道 Decorator 的存在的

  具体的装饰类:

      class ConcreteDecoratorA : Decorator
      {
          private string addedState;          //本类的独有功能,以区别于ConcreteDecoratorB

          public override void Operation()
          {
              base.Operation();       //首先运行原Component的Operation(),再执行本类的功能,如addedState,相当于对原Component进行了装饰
              addedState = "New State";
              Console.WriteLine("具体装饰对象A的操作");
          }
      }

      class ConcreteDecoratorB : Decorator
      {
          public override void Operation()
          {
              base.Operation();       //首先运行原Component的Operation(),再执行本类的功能,AddBehavitor(),相当于对原Component进行了装饰
              AddBehavitor();
              Console.WriteLine("具体装饰对象A的操作");
          }

          private void AddBehavitor()         //本类独有的方法,以区别于ConcreteDecoratorA
          {

          }
      }

  客户端代码:

        static void Main(string[] args)
        {
            ConcreteComponent c = new ConcreteComponent();
            ConcreteDecoratorA d1 = new ConcreteDecoratorA();
            ConcreteDecoratorB d2 = new ConcreteDecoratorB();

            d1.SetComponent(c);
            d2.SetComponent(d1);
            d2.Operation();         //装饰的方法是:首先用ConcreteComponent实例化对象c,然后用ConcreteDecoratorA的实例化对象d1来包装c,再用ConcreteDecoratorB的对象d2包装d1,最终执行d2的Operation()

            Console.Read();
        }

6.5 装饰模式的实际应用

  “Person” 类(ConcreteComponent)

      class Person
      {
          public Person()
          { }

          private string name;
          public Person(string name)
          {
              this.name = name;
          }

          public virtual void Show()
          {
              Console.WriteLine("装扮的{0}", name);
          }
      }

  服饰类(Decorator)

      class Finery : Person
      {
          protected Person component;

          //打扮
          public void Decorate(Person component)
          {
              this.component = component;
          }

          public override void Show()
          {
              if(component != null)
              {
                  component.Show();
              }
          }
      }

  具体服饰类(ConcreteDecorator)

    class TShirts : Finery
    {
        public override void Show()
        {
            Console.WriteLine("大T恤 ");
            base.Show();
        }
    }

    class BigTrouser : Finery
    {
        public override void Show()
        {
            Console.WriteLine("垮裤 ");
            base.Show();
        }
    }

  客户端代码

        static void Main(string[] args)
        {
            Person xc = new Person("小菜");

            Console.WriteLine("
第一种装扮:");

            BigTrouser kk = new BigTrouser();       //垮裤
            TShirts dtx = new TShirts();            //大T恤

            kk.Decorate(xc);            //装扮过程
            dtx.Decorate(kk);
            dtx.Show();

            Console.Read();
        }
原文地址:https://www.cnblogs.com/zhangchaoran/p/8538062.html