[Design Pattern]Decorator Pattern - 讀書筆記
參考書
目的
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)
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/

