繁体   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