3

我是模式编程的新手,我花了几个小时寻找用于模式观察器的 Smalltalk 实现的示例,但徒劳无功。如果有人可以为我提供在 Smalltalk 下实现此模式的具体示例,我将不胜感激。

4

3 回答 3

12

Smalltalk 中观察者模式的标准实现是#changed/#update机制。

它是这样的:

subject addDependent: anObserver.

subject changed.

然后anObserver发送#update

MyObservingObject>>update
  "I got called in a #changed chain"
  super update.
  self doUpdatingStuff

您可以使用#changed:and进行更好#update:的控制(注意冒号):

subject addDependent: anObserver.
subject changed: subject.

MyObservingObject>>update: anObject
  "I got called in a #changed: chain"
  super update: anObject.
  self doUpdatingStuffWith: anObject

但是,通常发现使用符号来指示发生了什么变化:

subject addDependent: anObserver.
subject changed: #myNumbers.

MyObservingObject>>update: anObject
  "I got called in a #changed: chain"
  anObject == #myNumbers ifTrue: [
    self doUpdatingStuffForNumbers.
    ^ self "inhibits the super"].
  super update: anObject.

当您查看SqueakPharo时,您会发现至少三个其他 Observer 实现:

  • Morphic 的事件处理(参见 参考资料Morph>>#on:send:to:
  • 类似的、更通用的事件处理机制,请参阅Object>>#when:send:to:Object>>#triggerEvent:
  • 公告框架,将主题和观察者之间的消息封装在类中。

您可以在Signals 项目中找到它们的比较,这是另一种实现,但受到 Qt 的启发。

于 2013-06-13T09:08:49.593 回答
5

最简单的方法是这样的:

在观察者类中:

observable: anObject
    observable := anObject.

observable
    ^ observable.

notify
    "do something here e.g.:"
    Transcript show: "Some things changed in ", observable asString.

在 Observable 中:

initialize
    observers := OrderedCollection new.

addObserver: anObserver
    observers add: anObserver.

removeObserver: anObserver
    observers remove: anObserver.

notifyObservers
    observers do: [ :each | each notify ].

但我也建议你在关于公告框架的章节中阅读更多关于这个想法的信息

于 2013-06-13T09:08:11.277 回答
2

另外,请查看公告框架。

它比发送符号更OO。

干杯

于 2013-06-13T20:28:29.917 回答