Java中的委托与回调
我对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); } }
它是回调还是委托( 委托和回调是相同还是相似? )?
如何实施另一个?
这是一个回调。 根据维基百科 :
在计算机编程中,回调是对一段可执行代码的引用,该代码作为参数传递给其他代码。
那么让我们看一下可执行代码:
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
使用策略模式 。 有两点需要注意:
-
getHelp()
的调用不涉及传递对可执行代码的引用。 即这不是回调。 -
MyObject.getHelp()
调用helpStrategy.getHelp()
这一事实在MyObject
对象的公共接口或getHelp()
调用中并不明显。 这种信息隐藏是授权的一些特征。
另外值得注意的是在getHelp()
方法中缺少// do something
section部分。 当使用回调时,回调不会执行与对象行为相关的任何操作:它只是以某种方式通知调用者,这就是为什么// 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 } }
我认为“回调”是一个通用模式的名称,您可以通过该方式为所述模块调用代码提供所调用的模块。 AC#delegate或ObjC委托对象(这两个是完全不同的beasts)或Java class-implementation-callback-interface是实现回调模式的不同的,特定于平台的方式。 (它们本身也可以被视为模式。)其他语言或多或少有不同的方式。
上面的“委托”概念也类似于策略模式,其中委托可以被认为是一个。 同样,访问者也是一种回调。 (访问者也是处理每个访问项目的策略。)
所有这些都使用对我来说很直观的定义,也可能不是对任何其他人的定义,因为“回调”或“委托”都不是正式术语,如果不参考之前的定义而对它们进行讨论是没有意义的。上下文。 因此,根据我的知识,没有一个权威的定义,因此询问定义是什么毫无意义。 也就是说,这个问题的其他答案可能会说完全不同的事实。
我的建议是专注于你的设计的优点 – 它是否达到你所需要的,不引入紧耦合等等 – 而不是语义的细节。 当两种设计模式看起来相似时,它们可能同样可以用来实现类似的目标。
您想要实现的是原始调用者和服务之间的双向通信,同时避免服务依赖于客户端。 您用于该目标的模式通常取决于您的语言的限制。 您可以使用函数指针,闭包,或者如果您没有这些,则使用回调对象(也可能被视为闭包)。
然后,对于相同或非常相似的模式,通常会有许多不同的名称。