在Smalltalk/VisualWorks中实现观察者模式



我是使用模式编程的新手,我花了几个小时寻找模式观察者的Smalltalk实现示例,但一无所获。如果有人能给我提供一个在Smalltalk下实现这个模式的具体示例,我将不胜感激。

在Smalltalk中可以找到的观察者模式的标准实现是#changed/#update机理

它是这样的:

subject addDependent: anObserver.
subject changed.

然后anObserver得到#update:

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

您可以使用#changed:#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.

当你看Squeak或Pharo时,你会发现至少有三个其他的观察者实现:

  • Morphic的事件处理(参见Morph>>#on:send:to:)
  • 一个类似的,更通用的事件处理机制,参见Object>>#when:send:to:Object>>#triggerEvent:
  • announcement 框架,封装类中主体和观察者之间的消息。

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

最简单的方法是:

:

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 ].

但是我也建议你在announcement Framework

一章中阅读更多关于这个想法的内容

另外,看看公告框架。

这比到处发送符号更OO。

欢呼

最新更新