簡體   English   中英

委托用法:業務應用程序

[英]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 的,但這仍然是基本思想。

除了圖形...

  1. 事件調度; 我的一些業務應用程序非常復雜,與硬件設備通信,並依靠事件隊列來保持一切同步。 這些應用程序使用委托來進行事件分派。
  2. 商業規則; 我的一些業務應用程序具有部分軟編碼能力,其中某些事件會觸發保存在數據庫中的某些規則。 委托(在字典中)用於在客戶端執行規則。 (可以支持插件,但不需要電流)。
  3. 通用二級線程(當然是使用 SafeThread class!)

據我所知,.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 泛型類型中,您可以使用以下項目:

  1. ConvertAll() - 使用委托將列表的所有成員轉換為另一種類型 (T)。 這基本上是 Map Function 的實現
  2. Find() 和 FindAll 都接受委托,並且將返回單個項目(在 Find() 的情況下)或導致傳入的委托評估為真的所有項目。 這提供了一個過濾器 function,以及一個謂詞的定義(一個 function 評估為布爾值)
  3. 有一個 ForEach() 方法的實現,它接受一個委托。 允許您對列表中的每個元素執行任意操作。

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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM