[Design Pattern] : 接口、抽象类的抽象合成
前言 :
面向对象设计守则里有一条:多用合成,少用继承。
面向对象设计守则的内容可以参考,
[深入浅出设计模式] : http://www.oreilly.com.tw/product_java.php?id=a163
本篇文章示范如何实作界面、抽象类的抽象合成,让合成之后的类别依然保有抽象方法。
使用时机 :
当有一堆抽象类,想要集合成一个大的抽象类时使用。
例如说
现在要实作Facade这个模式 可是有些抽象对象的方法,要让使用者去实作。 这个时候,抽象合成就可以派上用场。
结构 :
实作 :
首先先要有一个抽象类
public abstract class Strategy { public int ClassMethod001(string x) { return int.Parse(x); } public abstract string ClassMethod002(int x); }
再来就是抽象类的合成类别
public abstract class Context { // Properties private Strategy _strategy = null; // Constructor public Context() { // Agent _strategy = new StrategyAgent(this.ClassMethod002); } // Methods public int ClassMethod001(string x) { return _strategy.ClassMethod001(x); } public abstract string ClassMethod002(int x); // Class private class StrategyAgent : Strategy { // Delegate public delegate string ClassMethod002Delegate(int x); // Properties private ClassMethod002Delegate _classMethod002Delegate = null; // Constructor public StrategyAgent(ClassMethod002Delegate classMethod002Delegate) { #region Require if (classMethod002Delegate == null) throw new ArgumentNullException(); #endregion _classMethod002Delegate = classMethod002Delegate; } // Methods public override string ClassMethod002(int x) { return _classMethod002Delegate(x); } } }
最后我们就可以继承合成类别,来达成继承被合成抽象类的工作。
public class ContextA : Context { public override string ClassMethod002(int x) { return x.ToString("D3"); } } public class ContextB : Context { public override string ClassMethod002(int x) { return x.ToString("X2"); } }
执行
namespace ConsoleApplication1 { class Program { static void Main(string[] args) { ContextA contextA = new ContextA(); Console.WriteLine(contextA.ClassMethod001("255")); Console.WriteLine(contextA.ClassMethod002(255)); Console.WriteLine(); ContextB contextB = new ContextB(); Console.WriteLine(contextB.ClassMethod001("255")); Console.WriteLine(contextB.ClassMethod002(0xFF)); Console.ReadLine(); } } }
期許自己~
能以更簡潔的文字與程式碼,傳達出程式設計背後的精神。
真正做到「以形寫神」的境界。