Реализация шаблона наблюдателя в Smalltalk/VisualWorks

Я новичок в программировании с использованием шаблонов, я потратил несколько часов на поиск примеров для реализации обозревателя шаблонов в Smalltalk, но тщетно. Если кто-то может предоставить мне конкретный пример реализации этого шаблона в Smalltalk, я буду благодарен.

3 ответа

Решение

Стандартная реализация шаблона наблюдателя, который можно найти в 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, вы обнаружите как минимум три другие реализации Observer:

  • Обработка событий для Morphic (см. Morph>>#on:send:to:)
  • Аналогичный, более общий механизм обработки событий, см. Object>>#when:send:to: а также Object>>#triggerEvent:
  • структура объявлений, заключающая в себе сообщения между субъектом и наблюдателем в классах.

Вы можете найти их сравнение в проекте Signals, другой реализации, но вдохновленной Qt.

Проще всего было бы что-то вроде этого:

в классе Observer:

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

Но я бы также посоветовал вам больше узнать об этой идее в главе о структуре объявлений.

Кроме того, взгляните на структуру объявлений.

Это больше ОО, чем отправка символов вокруг.

ура

Другие вопросы по тегам