在 Smalltalk 中(更具体地说在 Pharo 中)进行委派的最佳方式是什么?我知道 doesNotUnderstand 策略,但它不会委托(delegate) subclassResponsability 消息。
我正在考虑将类上未显式实现的每条消息发送委托(delegate)给某个指定对象,就像我可以使用 Groovy 中的 @Delegate 所做的那样。有一些已知的方法可以做到这一点吗?
最佳答案
doesNotUndersand:
只适用于对象不理解的方法(因此得名),因此如果您已经实现了一个方法,它将不会被使用(就像 subclassResponsibility
的情况一样。
如果您使用 Pharo 5(将于本周(2016 年 5 月)发布),您可以使用 MetaLinks。这有点矫枉过正,但是您所做的事情一开始似乎并不正确(为什么您要委托(delegate)子类责任)?
无论哪种情况,MetaLink 都允许将运行时行为附加到您的方法,例如:
您有一些想要委托(delegate)的方法
MyObject>>someMethod
^ self subclassResponsiblity
以及您希望委托(delegate)给的对象...
MyObject>>delegate
^ delegate
因此您创建了一个 MetaLink
link := MetaLink new
metaObject: [ :object :selector :arguments |
object delegate perform: selector withArguments: argument ];
selector: #perform:withArguments:;
arguments: #(object selector arguments);
control: #instead.
您可以将其安装到您想要的任何方法 AST。
(MyObject>>someMethod ast) link: link.
现在每次调用该方法时,instead
(这就是 control:
所做的)执行该方法时,消息的参数(如果有)将被赋予 metaObject:
中的 block .
虽然这应该有效并且是非常强大的机制,但目前正在解决一些严重的缺点:
- 没有文档
- 工具支持很少(很难调试)
- 大量工作(我们正在开发一个框架来缓解这一问题,因为您希望轻松安装它们并在需要的任何地方卸载它们,但它尚未准备好,因此必须手动完成)<
- 重新编译会删除链接(请参阅上面的内容)
摘要
总而言之,正如我所展示的那样,这可以通过 MetaLinks 来完成,但目前需要做大量工作,但我们正在解决这些问题。
关于delegates - Pharo Smalltalk 中的委托(delegate)团,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/37122808/