在 C#語言對設計模式的支援中, delegate 是它很大的特色。delegate 可以將功能定義與功能實現分離,有利於設計職責分離的類結構。
delegate 的本質是函數指標。delegate 可以實現一個重要的概念是 callBack。什麼是 callBack 呢?可以用一個簡單的例子來說明: A 可以打電話告訴 B,要求 B 回個電話給 A。並且 A 在電話中可以規定 B 何時或何種情況下(這裡的情況是指 A 觀察的情況,而不是 B 出現何種情況。因為 A 不知道 B 的具體詳情。)給你回電話,但電話內容由 B 決定。這樣類 A 和 B 都可以有自己清晰的職責了。代碼也就優雅靈活了。
-------------------------------------------------
delegate 是類型,必須先聲明,再定義。然後才能使用。
聲明:public delegate 傳回值 委託名(參數列表).
定義: new 委託名(符合委託規範的方法或函數).
C#為了更靈活的支援這種 CallBack 的編程方法,在語言層級就聲明了幾種 delegate 。像基礎資料型別 (Elementary Data Type),可以直接定義使用。
1、 Event :是種特殊的委託,有固定的傳回值和參數列表。
2、 Func : 帶有1個傳回值的委託。有以下幾種形式:
public delegate TResult Func<TResult>();
public delegate TResult Func<T1,TResult>(T1,TResult)
public delegate TResult Func<T1,...,Tn,TResult>(T1,...,Tn,TResult)
3、 Action: 沒有傳回值的委託。也有多種形式:
public delegate void Func<TResult>();
public delegate void Func<T1,...,Tn>(T1,...,Tn);
具體 Delegate 會運用哪些模式中?例如可以運用在 Template Method (模板方法) 中,運用 observer (觀察者)模式等。
在傳統的 Template Method 模式中要為每個 Method的實現開發一個子類。這就會帶來子類過多的問題。於是可以利用 Delegate 在 Template 中定義抽象實現,在 用戶端(應用環境)中實現具體的 Method 。這樣既可以減少 Method 子類的數量,又可以達到具體實現與 Template 的解耦。
同樣可以利用 delegate 消除 Observer 模式中介面的定義。
例子:
應用環境:
系統要實現給不同性質的目標傳送簡訊:1、A群-要到tableA處取他們的電話號碼;2、B群-要到tableB處取他們的電話號碼。3、C 帳號-要到......得到手機號;4、D 手機號-直接輸入手機號。
將來還有可能會其他的擷取電話號碼的手段。如何來設計我們的系統呢?如何面對以後的變化呢?
分析:
在這個流程中,雖然擷取電話號碼列表的方法不同,但是傳送簡訊的流程是相同的。取得號碼列表——判斷列表——傳送簡訊。問題現在就清除了,我們的變化點只是在取得號碼列表的方法上。於是我們可以將傳送簡訊的流程進行封裝 Message.cs,通過 delegate 將如何取簡訊公布出來,因為如何取得號碼列表只有發送的簡訊的人才是最清楚 MessageBiz 中封裝了不同取得簡訊的方法。
應用:
這樣之後我們只要在頁面中將不同的取得簡訊的方法分配給 Message Class 就可以了。Message 中不會再有大量讓人頭痛的if else 了。更不用害怕以後有不同的取號方法,使得if else 越變越大,最後成為系統的累贅。