【问题标题】:What are some good use cases for the CALLBACK pattern/idiom?CALLBACK 模式/习语有哪些好的用例?
【发布时间】:2009-10-08 17:38:29
【问题描述】:

我不使用这种模式,也许在某些地方它本来是合适的,我使用了其他东西。你在日常编码中使用过它吗?随意以您选择的语言提供示例,并附上您的解释。

【问题讨论】:

  • 有几种叫做“回调模式”的东西;请提供一个简短的定义,以便我们知道您在说哪一个。

标签: language-agnostic design-patterns


【解决方案1】:

回调并不是真正的“模式”——更像是一个构建块。许多gang of four design patterns 以类似回调的方式使用虚拟方法。 Justin Niessner 已经提到了Observer

回调比 OOP 早得多(并且可能比 3GL 甚至汇编程序更早)。另一个老想法是参数块 - C 解释是一个结构,其中包含要传递给函数的相关成员,因此函数不需要巨大的参数列表。

OOP 类建立在参数块之上(并为其添加一种哲学)。类实例本身是一个通过引用其方法传递的参数块。虚拟表是一个调度处理参数块。每个虚方法在调度处理参数块中都有一个回调指针。纯虚方法在参数块中为回调指针预留空间,并承诺稍后提供实际指针。

由于类是面向对象设计模式的构建块,而参数块和回调是类的构建块 - 好吧,您可以声称所有 OOP 设计模式都是基于这些想法构建的。

我想说“参数块和回调,加上指导它们使用的样式规则,启发了面向对象”,但听起来很吸引人,我不知道这是否属实。

【讨论】:

    【解决方案2】:

    我几乎每天都在以下场景中使用回调:

    • 事件:当用户在控件上单击鼠标、按下键或以我需要处理的方式与 UI 交互时,我订阅了控件为事件发布的委托。然后我可以通过更新 UI、在某些情况下取消事件或采取一些特殊措施来处理它。

    • 多线程编程:在编写 GUI 时,保持 UI 响应并向用户指示长时间运行的后台事件的进度非常重要。为此,我在一个单独的线程中启动任务,然后发布委托(.NET 世界中的事件),为我的 UI 提供通知用户正在发生的进度的机会。

    • Lambda 函数:在 .NET 中,lambda 函数是委托的一种形式,它允许我在稍后的时间点与另一段代码的操作进行交互。 LINQ 就是一个很好的例子。我可以创建一个小的匹配函数,然后将其提供给 LINQ 查询。稍后,当我对集合执行查询时,会调用匹配函数来确定查询是否匹配。这使我不必构建或担心查询机制。我只需要告诉查询机制去哪里找出比较是否匹配。

    我敢肯定,这些例子只是表面上的。但它们是我每天如何使用回调的有用示例。

    【讨论】:

      【解决方案3】:

      .NET 平台大量使用回调来实现观察者模式。

      它们还用于处理异步进程。

      【讨论】:

        【解决方案4】:

        Objective C 和 Cocoa 框架大量使用它。一个例子是NSURLConnection,当连接上发生某些事情时,它将通知给它的对象(称为它的delegate):

        NSURLConnection *foo = [[NSURLConnection alloc] initWithRequest:request delegate:self];
        

        注意delegate 的传递。请求在后台进行,然后实例将向委托(在本例中为self)发送消息,例如:

        connectionDidFinishLoading:
        connection:didFailWithError:
        

        你明白了。我相信这被称为“观察者模式”。这一切都与 Cocoa 的事​​件循环有关(据我所知,我还在学习),并且是便宜且简单的异步编程。许多不同语言的框架都遵循这种方法。

        .NET 也有类似的委托。思考事件。

        【讨论】:

          【解决方案5】:

          我在 javascript 中大量使用它来让我知道异步调用何时完成,以便处理结果。

          但是,在 javascript 中,现在在 C#3 中,我将函数作为参数传递,这样处理就可以继续进行,而无需显式设置要调用的委托。

          【讨论】:

            猜你喜欢
            • 2011-05-11
            • 2011-01-01
            • 2011-10-30
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            相关资源
            最近更新 更多