文章出處

索引

意圖

預期對象的接口將在未來被擴展。通過額外的接口來定義擴展對象。

Anticipate that an object’s interface needs to be extended in the future.

Additional interfaces are defined by extension objects..

結構

參與者

Subject

  • 定義抽象主體對象。其定義用于查詢是否包含特定擴展的接口。

Extension

  • 所有擴展類的抽象基類。可以定義負責管理擴展自身的操作。
  • Extension 知道其是誰的擴展。

ConcreteSubject

  • 具體的主體類。實現基類定義的 GetExtension 方法并返回相應的擴展對象。

AbstractExtension

  • 特定種類的擴展類的抽象基類。

ConcreteExtension

  • 繼承并實現 AbstractionExtension 類。實現特定的擴展功能。

適用性

當以下情況成立時可以使用 Extension Object 模式:

  • 當需要為已有對象額外添加全新的或無法預見的接口時。
  • 抽象的主要接口在不同的客戶類中擁有不同的角色時。
  • 無法通過子類型化來擴展接口行為時。

效果

  • 擴展對象促進了增加新擴展功能。
  • 類的主要抽象接口不會過于膨脹。
  • 接口的主要抽象在不同的子系統中可實現不同的角色。
  • 客戶類變得更加復雜。
  • 需要控制對擴展對象的濫用。

相關模式

  • Visitor 模式可以為層級的類結構增加新的行為。Visitor 模式與 Extension Object 模式擁有類似的益處。相比 Visitor 模式,Extension Object 模式不需要一個穩固的類層級結構,并且也不引入循環依賴。
  • Decorator 模式是另一個可以擴展類的行為的模式。客戶類在使用 Decorator 對象時的透明性比使用 Extension Object 更好。在使用窄接口或需要增強已知接口時更適合使用 Decorator 模式。
  • Adapter 模式支持適配一個已知接口。Extension Object 模式支持附加的接口。當對象需要對擴展接口進行適配時可以同時使用 Extension Object 模式和 Adapter 模式。

實現

實現方式(一):使用示例結構實現 Extension Object。

 1 namespace ExtensionObjectPattern.Implementation1
 2 {
 3   public abstract class Subject
 4   {
 5     public abstract void Operation1();
 6     public abstract Extension GetExtension(string extensionType);
 7   }
 8 
 9   public abstract class Extension
10   {
11     protected Subject _owner;
12 
13     public Extension(Subject owner)
14     {
15       _owner = owner;
16     }
17 
18     public abstract void DoSomething();
19   }
20 
21   public abstract class AbstractExtension : Extension
22   {
23     public AbstractExtension(Subject owner)
24       : base(owner)
25     {
26     }
27   }
28 
29   public class ConcreteExtension : AbstractExtension
30   {
31     public ConcreteExtension(Subject owner)
32       : base(owner)
33     {
34     }
35 
36     public override void DoSomething()
37     {
38       // do something
39       _owner.Operation1();
40     }
41   }
42 
43   public class ConcreteSubject : Subject
44   {
45     private ConcreteExtension _extension;
46 
47     public ConcreteSubject()
48     {
49       _extension = new ConcreteExtension(this);
50     }
51 
52     public override void Operation1()
53     {
54       // do something
55     }
56 
57     public override Extension GetExtension(string extensionType)
58     {
59       if (extensionType == "some type")
60       {
61         return this._extension;
62       }
63 
64       return null;
65     }
66   }
67 
68   public class Client
69   {
70     public void TestCase1()
71     {
72       Subject subject = new ConcreteSubject();
73       Extension extension = subject.GetExtension("some type");
74       extension.DoSomething();
75     }
76   }
77 }

實現方式(二):使用泛型實現 IExtensibleObject<T> 接口。

 1 namespace ExtensionObjectPattern.Implementation2
 2 {
 3   public abstract class Subject : IExtensibleObject<Subject>
 4   {
 5     public abstract void Operation1();
 6     public abstract IEnumerable<IExtension<Subject>> Extensions { get; }
 7   }
 8 
 9   public interface IExtensibleObject<T>
10     where T : class, IExtensibleObject<T>
11   {
12     IEnumerable<IExtension<T>> Extensions { get; }
13   }
14 
15   public interface IExtension<T>
16     where T : class, IExtensibleObject<T>
17   {
18     void Attach(T owner);
19     void Detach(T owner);
20   }
21 
22   public abstract class Extension : IExtension<Subject>
23   {
24     protected List<Subject> _owners;
25 
26     public void Attach(Subject owner)
27     {
28       _owners.Add(owner);
29     }
30 
31     public void Detach(Subject owner)
32     {
33       _owners.Remove(owner);
34     }
35 
36     public abstract void DoSomething();
37   }
38 
39   public class ConcreteExtension : Extension
40   {
41     public override void DoSomething()
42     {
43       // do something
44       foreach (var item in _owners)
45       {
46         item.Operation1();
47       }
48     }
49   }
50 
51   public class ConcreteSubject : Subject
52   {
53     private List<Extension> _extensions = new List<Extension>();
54 
55     public ConcreteSubject()
56     {
57       Extension extension = new ConcreteExtension();
58       extension.Attach(this);
59 
60       _extensions.Add(extension);
61     }
62 
63     public override void Operation1()
64     {
65       // do something
66     }
67 
68     public override IEnumerable<IExtension<Subject>> Extensions
69     {
70       get
71       {
72         return _extensions;
73       }
74     }
75   }
76 
77   public class Client
78   {
79     public void TestCase1()
80     {
81       Subject subject = new ConcreteSubject();
82 
83       foreach (var extension in subject.Extensions)
84       {
85         (extension as Extension).DoSomething();
86       }
87     }
88   }
89 }

設計模式之美》為 Dennis Gao 發布于博客園的系列文章,任何未經作者本人同意的人為或爬蟲轉載均為耍流氓。


文章列表


不含病毒。www.avast.com
arrow
arrow
    全站熱搜

    大師兄 發表在 痞客邦 留言(0) 人氣()