Design patterns smalltalk中代理模式的实现

Design patterns smalltalk中代理模式的实现,design-patterns,smalltalk,Design Patterns,Smalltalk,我在smalltalk中阅读代理模式实现,它是使用doesNotUnderstand实现的。 我没有弄明白这个方法什么时候会像场景中那样被调用。有人能给我一个例子/场景吗。不理解:或者如果方法查找失败,就会调用DNU而不是原始消息。下面的例子 nil aSelectorThatDoesNotExist 触发对象上的默认DNU,这将引发messagenotUnderstanding异常 您可以使用doesNotUnderstand:协议轻松地将消息发送委托给另一个对象。例如,如果我在我的代理上添

我在smalltalk中阅读代理模式实现,它是使用doesNotUnderstand实现的。
我没有弄明白这个方法什么时候会像场景中那样被调用。有人能给我一个例子/场景吗。

不理解:
或者如果方法查找失败,就会调用DNU而不是原始消息。下面的例子

nil aSelectorThatDoesNotExist
触发对象上的默认DNU,这将引发
messagenotUnderstanding
异常

您可以使用
doesNotUnderstand:
协议轻松地将消息发送委托给另一个对象。例如,如果我在我的
代理上添加以下方法

doesNotUnderstand: aMessage
    ^ target perform: aMessage selector withArguments: aMessage arguments
它将把未在
代理
本身上实现的所有消息转发给另一个
目标
对象。这里很重要的一点是,
代理
对象应该实现尽可能少的方法,否则它们不能被转发。出于这个原因,我们需要一个只实现一组基本方法的
ProtoObject
。通常,代理继承自
ProtoObject

更基本地说,“perform”类似于Lisp的“apply”。(apply a函数anArgumentList)

函数和参数列表是要计算的表达式

示例:

(适用于(car'(*+)'(2 3 4)) =24

(适用(cadr'(*+)'(2 3 4)) =9


它可以实现计算的函数调用(扩展为计算的消息发送)。

也许关于如何/为什么调用
#doesnotunstand:
的注释可能有用。@dh82感谢您的解释。执行类似于传递选择器和参数的操作,然后在运行时执行选择器。你能告诉我为什么和什么时候使用perform吗?@Jiten:你说得对。这就像Ruby的
Object#send
方法一样。当您在运行时之前不知道要发送什么消息时,就需要它。理想情况下,你应该尽可能少地使用它,因为这使得代码很难理解:工具的发送者/实现者变得不那么有用。@Frankshierar:在这种情况下,我们每次都使用代理对象,但是如果代理和真实主体是从同一个主体继承的,那么代理怎么可能没有一些方法呢(真实的subject和proxy将有相同的方法集,对吗)?因此它的DoetUnderstand被调用。如果proxy继承自subject的超类,并且超类定义了所有的方法,那么你肯定不会得到一个DNU。但在这种情况下,你是在手工编写DNU免费提供给你的东西(代价是失去明确的契约)。