【问题标题】:Delegate vs Callback in JavaJava中的委托与回调
【发布时间】:2012-09-21 05:16:57
【问题描述】:

我对 Java 中的委托和回调术语有一些误解。

class MyDriver {

    public static void main(String[] argv){
        MyObject myObj = new MyObject();
        // definition of HelpCallback omitted for brevity
        myObj.getHelp(new HelpCallback () {
            @Override
            public void call(int result) {
                System.out.println("Help Callback: "+result);
            }
        });
    }
}

class MyObject {

    public void getHelp(HelpCallback callback){
        //do something
        callback.call(OK);
    }
}

是回调还是委托(Are delegates and callbacks the same or similar?)?

那么如何实现另一个呢?

【问题讨论】:

  • 基于“委托”和“回调”的哪个定义? Delegate 表示基于上下文的一堆东西,例如 Objective-C 和 C# 的含义有很大不同。
  • 我只对 Java 和 Objective C 的上下文感兴趣(我想知道如何在纯 Java 中实现它)。
  • 接受的答案是关于 C#,这显然不是你的情况。此外,您不能只说“例如”。我的观点是,即使你真的非常非常迂腐,设计模式之间也没有真正的硬性区别。
  • 我有点困惑,因为在开始学习 Objective C 时,我遇到了与 java 回调非常相似的委托 -> 所以我想感受一下它们之间的区别。

标签: java design-patterns delegates callback


【解决方案1】:

我认为“回调”是一种通用模式的名称,在这种模式下,您可以为要调用的模块提供一种让所述模块调用您的代码的方式。 C# 委托或 ObjC 委托对象(这两者是完全不同的野兽)或 Java 类实现回调接口是不同的、特定于平台的回调模式的实现方式。 (它们本身也可以被视为模式。)其他语言或多或少有细微的不同。

上述“委托”的概念也类似于策略模式,其中委托可以被认为是一个。同样,Visitor 也是一种回调类型。 (访问者也是处理每个访问项目的策略。)

所有这些都是使用对我来说直观的定义,可能对其他人来说不是,因为“回调”或“委托”都不是正式术语,如果不参考之前的定义就讨论它们是没有意义的在您的上下文中有效。因此,询问定义是什么毫无意义,因为据我所知,没有权威的定义。也就是说,这个问题的其他答案可能会说完全不同的东西。

我的建议是关注设计的优点——它是否能满足你的需要,是否引入了紧密耦合等——而不是语义上的细枝末节。当两种设计模式看起来相似时,它们可能同样可以用来实现相似的目标。

【讨论】:

    【解决方案2】:

    您想要实现的是原始调用者和服务之间的双向通信,同时避免服务依赖于客户端。您用于该目标的模式通常取决于您的语言限制。您使用函数指针、闭包,或者,如果您没有这些,则使用回调对象(也可能被视为闭包)。

    对于相同或非常相似的模式,通常会有很多不同的名称。

    【讨论】:

      【解决方案3】:

      这是一个回调。 According to Wikipedia:

      在计算机编程中,回调是对作为参数传递给其他代码的一段可执行代码的引用。

      那么我们来看看可执行代码:

      public void getHelp(HelpCallback callback){
          //do something
          callback.call(OK);
      }
      

      这里,callback 参数是对HelpCallback 类型对象的引用。由于该引用是作为参数传入的,因此它是一个回调。

      委托示例

      委托由对象在内部完成 - 与调用方法的方式无关。例如,如果callback 变量不是参数,而是实例变量:

      class MyDriver {
      
          public static void main(String[] argv){
              // definition of HelpStrategy omitted for brevity
              MyObject myObj = new MyObject(new HelpStrategy() {
                  @Override
                  public void getHelp() {
                      System.out.println("Getting help!");
                  }
              });
              myObj.getHelp();
          }
      
      }
      
      class MyObject {
          private final HelpStrategy helpStrategy;
      
          public MyObject(HelpStrategy helpStrategy) {
              this.helpStrategy = helpStrategy;
          }
      
          public void getHelp(){
              helpStrategy.getHelp();
          }
      }
      

      ...那就是委托。

      这里,MyObject 使用 strategy pattern。有两点需要注意:

      1. getHelp() 的调用不涉及传递对可执行代码的引用。也就是说,这不是回调。
      2. MyObject.getHelp() 调用helpStrategy.getHelp() 的事实在MyObject 对象的公共接口或getHelp() 调用中并不明显。这种information hiding 有点委托的特征。

      另外值得注意的是getHelp() 方法中缺少// do something 部分。当使用回调时,回调不会做任何与对象行为相关的事情:它只是以某种方式通知调用者,这就是为什么需要 // do something 部分的原因。然而,当使用委托时,方法的实际行为取决于委托——所以实际上我们最终可能需要两者,因为它们有不同的用途:

          public void getHelp(HelpCallback callback){
              helpStrategy.getHelp(); // perform logic / behavior; "do something" as some might say
              if(callback != null) {
                  callback.call(); // invoke the callback, to notify the caller of something
              }
          }
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2014-11-16
        • 1970-01-01
        • 1970-01-01
        • 2013-03-13
        • 2014-11-06
        • 2012-01-15
        • 2011-01-12
        相关资源
        最近更新 更多