[Design Pattern]Decorator Pattern - 讀書筆記

  • 9405
  • 0

[Design Pattern]Decorator Pattern - 讀書筆記

參考書

C# 3.0 Design Patterns

 

目的

Add new functionality dynamically to existing objects, or remove it

針對基底object動態地新增function或移除function,也可賦予新的operation或state

 

特性

  • The original object is unaware of any decorations.
  • There is no one big feature-laden class with all the options in it.
  • The decorations are independent of each other.
  • The decorations can be composed together in a mix-and-match fashion.

簡單的說,新的object與原本的object都一樣,
透過interface的implement可以比用inheritance+overrides來的更有彈性。
(如果你只會有一個新的object,那就可以直接用inheritance,通常為了保留彈性,還是會用implement)

書上的例子相單簡單易懂,
UML

is A的部分,為Implement。
has A的部分,則是將Interface丟進去新的object(即新的Decorator) 建構式。

程式碼的部分也相當好理解,

  using System;

  class DecoratorPattern {

    // Decorator Pattern             Judith Bishop  Dec 2006
    // Shows two decorators and the output of various
    // combinations of the decorators on the basic component

     interface IComponent {
        string Operation();
      }

      class Component : IComponent {
        public string Operation () {
          return "I am walking ";
        }
      }

       class DecoratorA : IComponent {
         IComponent component;

         public DecoratorA (IComponent c) {
           component = c;
         }

         public string Operation() {
           string s = component.Operation();
           s += "and listening to Classic FM ";
           return s;
         }
       }

       class DecoratorB : IComponent {
         IComponent component;
         public string addedState = "past the Coffee Shop ";

         public DecoratorB (IComponent c) {
           component = c;
         }

          public string Operation () {
            string s = component.Operation ();
            s += "to school ";
            return s;
          }

          public string AddedBehavior() {
            return "and I bought a cappuccino ";
          }
        }

      class Client {

        static void Display(string s, IComponent c) {
          Console.WriteLine(s+ c.Operation());
        }

        static void Main() {
          Console.WriteLine("Decorator Pattern\n");

          IComponent component = new Component();
          Display("1. Basic component: ", component);
          Display("2. A-decorated : ", new DecoratorA(component));
          Display("3. B-decorated : ", new DecoratorB(component));
          Display("4. B-A-decorated : ", new DecoratorB(
                  new DecoratorA(component)));
          // Explicit DecoratorB
          DecoratorB b = new DecoratorB(new Component());
          Display("5. A-B-decorated : ", new DecoratorA(b));
          // Invoking its added state and added behavior
          Console.WriteLine("\t\t\t"+b.addedState + b.AddedBehavior());
        }
      }
    }

結果


/* Output
Decorator Pattern
1. Basic component: I am walking
2. A-decorated : I am walking and listening to Classic FM
3. B-decorated : I am walking to school
4. B-A-decorated : I am walking and listening to Classic FM to school
5. A-B-decorated : I am walking to school and listening to Classic FM
past the Coffee Shop and I bought a cappuccino
*/


建議大家可以先從結果開始看,接著看Main(),再推回去看每一個class,搭配UML服用。

重點解釋:

  • 每一個instance都是IComponent
  • Component為每個instance的基底,且自己也是一個完整的instance
  • Decorator的instance建構式,將IComponent丟進來當作參數,即可使用丟進來的IComponent的operation。
  • Decorator除了可以使用丟進來的IComponent的operation,還可以定義自己實作IComponent的operation或attribute。
  • 可以延伸出無限多種Decorator來implement自己期望的IComponent。

最後在強調一下,Decorator Pattern最主要的目的,
是用來解決如何針對一個基底的object,
動態地去新增、移除新的或已經存在的function,不用繼承,也可以修改新object的attribute或operation。


blog 與課程更新內容,請前往新站位置:http://tdd.best/