[Object-oriented] : 介面、抽象類別的合成
前言 :
物件導向設計守則裡有一條:多用合成,少用繼承。
物件導向設計守則的內容可以參考,
[深入淺出設計模式] : 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();
}
}
}
簽名檔
期許自己能以更簡潔的文字與程式碼,傳達出程式設計背後的精神。
真正做到「以形寫神」的境界。