Domanda

I'm new to programming with patterns, i spent some hours searching for samples for Smalltalk implementation of the pattern observer but in vain. If someone can provide me with a concrete sample of the implementation of this pattern under Smalltalk, i will be thankful.

È stato utile?

Soluzione

The standard implementataion of the observer pattern to be found in Smalltalk would be the #changed/#update mechanism.

It goes like this:

subject addDependent: anObserver.

subject changed.

and then anObserver gets send #update:

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

You can have finer control using #changed: and #update: (note the colon):

subject addDependent: anObserver.
subject changed: subject.

and

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

However, it is commonly found to use a symbol to indicate what changed:

subject addDependent: anObserver.
subject changed: #myNumbers.

and

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

When you look at Squeak or Pharo, you'll find at least three other Observer implementations:

  • The event handling for Morphic (see Morph>>#on:send:to:)
  • A similar, more general event handling mechanism, see Object>>#when:send:to: and Object>>#triggerEvent:
  • the Announcements framework, encapsulating messages between subject and observer in classes.

You can find a comparison of these at the Signals project, another implementation, but inspired by Qt.

Altri suggerimenti

The easiest way would be something like this:

in Observer class:

observable: anObject
    observable := anObject.

observable
    ^ observable.

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

And in Observable:

initialize
    observers := OrderedCollection new.

addObserver: anObserver
    observers add: anObserver.

removeObserver: anObserver
    observers remove: anObserver.

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

But I'd also suggest you to read more about this idea in the chapter about Announcements Framework

Also, take a look at Announcements Framework.

It is more OO than sending symbols around.

Cheers

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top