[英]Delegate Usage : Business Applications
鑒於“大多數”開發人員都是業務應用程序開發人員,我們最喜歡的編程語言的特性在我們正在使用它們的上下文中使用。
作為一名 C# / ASP.NET 應用程序開發人員,我傾向於在處理 UI 事件時只使用委托。 事實上(這是我缺乏經驗的一部分),除了使用代表的事件之外,我什至不知道一個好的上下文! 這很可怕; 但我正在收集其他開發人員在同一條船上。
注意:答案應與 .NET 2.0 有關。 .NET 3.0 將代表完全帶到了一個不同的水平,這可能是一個單獨的問題。
除了事件之外,委托有多有用,在哪些業務應用程序上下文中它們最有用?
更新: Jarrod Dixon幫助鏈接到 MSDN 文檔關於委托使用,我必須承認我最喜歡的設計模式書根本沒有提出委托,所以除了 UI 事件之外,我還沒有真正看到它們在使用中。 為了擴展這個問題(只是一點點),您可以為業務應用程序(或者真的?任何必須處理相關問題的應用程序)提供哪些示例,以便更容易消化有關該主題的 MSDN 文檔?
我認為這個問題反映了給貓剝皮的多種方法。 我發現委托(和 lambda)幾乎與“for”循環一樣基本。
這是我最近使用代表的一種情況(出於演示目的而更改了格式和名稱:)
protected T[] SortLines<T>(Func<T> createLine, IEnumerable<T> unsorted)
where T : LineType
{
Func<IEnumerable<T>, IEnumerable<T>> sorter = (lines => lines);
switch (settings.OrderSort)
{
case OrderSort.ByA:
sorter = (lines => lines.OrderBy(x => x.A)); break;
case OrderSort.ByB:
sorter = (lines => lines.OrderBy(x => x.B)); break;
// and so on... a couple cases have several levels of ordering
}
bool requiresSplit = // a complicated condition
if (requiresSplit)
{
var positives = unsorted.Where(x => x.Qty >= 0);
var negatives = unsorted.Where(x => x.Qty < 0);
return sorter(negatives).Concat(
new T[] { createLine.Invoke() }).Concat(
sorter(positives)).ToArray();
}
else
return sorter(unsorted).ToArray();
}
因此,這會根據某些標准對一組項目進行排序,然后它要么返回已排序的整個列表,要么將其分成兩部分,分別對兩半進行排序,並在它們之間放置一個分隔符。 如果你不能表達“一種排序方式”的概念,那么祝你好運,這就是委托的目的。
編輯:我猜 Concat 和 OrderBy 是特定於 3.0 的,但這仍然是基本思想。
除了圖形...
據我所知,.NET 委托本質上是單方法接口的實現,沒有所有 class 聲明。 我希望我們親自將它們放在 Java 中。 想想比較器 class:
class MyComparator<Circle> extends Comparator<Circle> {
public int compare(Circle a, Circle b) {
return a.radius - b.radius;
}
}
在這種模式有用的任何地方,委托都可能有用。
我希望我是對的,但 go 領先,如果我錯了,請投票給我; 我已經很久沒有看到任何 C# 了:)
代表的另一個重要用途是 state 機器。 如果您的程序邏輯包含重復的 if...then 語句來控制它所在的 state,或者如果您使用復雜的開關塊,您可以輕松地使用它們來復制 State 模式。
enum State {
Loading,
Processing,
Waiting,
Invalid
}
delegate void StateFunc();
public class StateMachine {
StateFunc[] funcs; // These would be initialized through a constructor or mutator
State curState;
public void SwitchState(State state) {
curState = state;
}
public void RunState() {
funcs[curState]();
}
}
我的 2.0 委托語法可能生銹了,但這是 state 調度程序的一個非常簡單的示例。 還要記住,C# 中的代表可以執行多個 function,允許您擁有一台 state 機器,每個 RunState() 執行任意多個函數。
每當您執行任何異步操作時,例如進行 web 服務調用,您都可以使用委托,因此當調用返回時,您可以發起委托調用,以便目標處理事情。
多年來我看到的一種常見模式(在各種語言中)是“凍結”決定將邏輯從循環中移到設置中的結果。 在偽代碼中(因為技術因語言而異):
some_condition = setup_logic
...
while (not terminated) {
data = obtain_data
if (some_condition)
process_one (data)
else
process_two (data)
}
關鍵是如果some_condition
沒有根據循環中的任何內容而改變,那么重復測試它真的沒有任何好處。 代表/關閉/等。 允許將上述內容替換為:
some_condition = setup_logic
if (some_condition)
selected_process = process_one
else
selected_process = process_two
...
while (not terminated) {
data = obtain_data
selected_process (data)
}
(當然,真正的函數式程序員會將設置編寫為:
selected_process = if (some_condition) process_one else process_two
;-)
這很好地概括了多種選擇(而不僅僅是兩個)。 關鍵思想是提前決定在未來一個(或多個)點采取什么行動,然后記住選擇的行動,而不是決策所基於的價值。
當您開始將委托視為功能構造時,委托會變得非常強大
.Net 2.0 包括對匿名代表的支持,它形成了 Linq 擴展的一些功能概念的 kernel。 匿名委托的語法比 Lambda 提供的要大一些,但很多核心功能模式都在 2.0 中。
在 List 泛型類型中,您可以使用以下項目:
Appart from List specific items,當您使用匿名委托上下文得到正確處理時,您可以實現類似閉包的結構。 或者,在更實際的層面上做類似的事情:
ILog logger = new Logger();
MyItemICareAbout.Changed += delegate(myItem) { logger.Log(myItem.CurrentValue); };
它只是工作。
還有 DynamicMethod 的東西,它允許您定義 IL 位(使用 Reflection.Emit),並將它們編譯為委托。 這為您提供了一個很好的替代純反射的方法,例如映射層和數據訪問代碼。
委托實際上是一個允許您將可執行代碼表示為數據的結構。 一旦你明白這意味着什么,就有很多事情可以做。 與 3.5 相比,2.0 中對這些構造的支持是基本的,但仍然存在,並且仍然非常強大。
委托通常用於事件調度,但這只是因為它們這樣做很方便。 委托對任何類型的方法調用都很有用。 它們還具有許多附加功能,例如異步調用的能力。
委托的基本原因是提供一個Closure或調用 function 及其 state 的能力,這通常是一個 object 實例。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.