委托模式的目的是什么?

55
我正在查看Android中的SensorManager的源代码(SensorManager),发现当你注册一个SensorEventListener时,SensorManager会将控制权转移给ListenerDelegate
我拿这个作为例子只是想说明一下。我已经阅读了有关委派编程的维基百科文章(the Wikipedia article),但我仍然不确定它的目的。为什么要使用“代理”?它如何帮助程序的控制流?使用(或不使用)它的缺点是什么?它最适合用于监听器吗?
编辑:ListenerDelegate在第487行,相关方法在第1054左右。

减少一个类的职责。 - pavel_orekhov
4个回答

78

在 GoF 书中所指的意义上,委托并不是一个“设计模式”。它在许多场景下非常有用,并且是其他模式的基础。

  • 当您想在委托前/后执行一些附加操作时(这就是装饰器模式,但它基于委托)。例如,Collections.synchronizedList(..)创建了一个代理到原始列表的新列表,但其方法已同步。
  • 当您拥有不兼容的接口并且希望将一个适配到另一个接口时(适配器模式)。您获取原始对象并从符合所需接口的方法中委托给它。例如,有一个 EnumerationIterator 类,它将枚举适配到 Iterator 接口。该类具有一个 hasNext() 方法,该方法委托给 enumeration.hasMoreElements()
  • 当您想要隐藏类的用户的一些复杂性时,可以有一些委托给不同实际工作者的方法。例如,汽车可以有 start()openWindow()brake(),但是每个方法实际上都将委托给引擎、电动窗户和制动系统(另请参见此处

2
你第三点(汽车示例)中定义的模式叫什么名字? - EmptyData
3
@EmptyData,这是门面模式。 - Chris Keller
2
谈到委托,使用@Delegate lombok注解在任何字段上,让lombok生成委托方法,将调用转发到该字段。 - elirandav

28
根据Joshua Bloch的《Effective Java》所述,组合优于继承。相比继承,组合有几个优点。其中之一的直觉是:考虑一个从基类继承的子类。因此,任何对基类的更改都会使得子类变得脆弱,因为子类依赖于基类。通过使用继承,我们让子类依赖于基类,这使得我们的代码变得脆弱。然而,通过使用组合,我们可以消除这种限制。组合是通过建立类之间的“拥有关系”而不是继承中的“is-a”关系来实现的。“委托模式”和“装饰者模式”都是如何实现组合的示例。您可能想阅读《Effective Java》书中有关“组合与继承”的章节,因为它非常详细。
更简短的解释,请参考以下文章:http://javarevisited.blogspot.com/2013/06/why-favor-composition-over-inheritance-java-oops-design.html

7
委托模式用于让其他人来实际完成工作,例如,在您的示例中,SensorManager 不知道如何做每个侦听器想要的事情,但您只希望一个程序侦听传感器。

因此,通过在SensorManager上调用 registerListener 来创建侦听器,然后将这些侦听器传递信息,然后可以决定如何处理来自传感器的数据。


2
在一个非常简单的句子中,我可以说:委托的主要目的是保护您的对象免受软件中其他对象实现变更的影响。阅读更多,请点击此处

这个链接几乎没什么用处。 - Adrian
我向你推荐这本书。 - Alireza Rahmani Khalili
Stackoverflow的意义在于提供答案,而不是像书籍一样需要付费。此外,我猜这本书有很多页,但你没有提到具体要阅读哪一页或哪个段落来支持你的答案 - 至少你声称它有帮助(但也许它并没有,这只是你的说法)。 - Adrian
1
答案已经在那里了,如果需要进一步阅读,您可以免费下载这本书。 - Alireza Rahmani Khalili

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接