Observer, Strategy, Decorator, Prototype,

Post on 06-Jan-2016

36 views 3 download

description

Observer, Strategy, Decorator, Prototype,. Observer Pattern. Dependence mechanism / publish-subscribe / event handler / constraints / broadcast Let objects propagate information without depending on each other much. - PowerPoint PPT Presentation

Transcript of Observer, Strategy, Decorator, Prototype,

Observer, Strategy, Decorator, Prototype,

Observer Pattern

Dependence mechanism / publish-subscribe / event handler / constraints / broadcast

Let objects propagate information without depending on each other much.

Define a one-to-many dependency between objects so that when one object changes state, all its dependents are notified and updated automatically.

Observer Pattern

ObserverObserver

update:update:

SubjectSubject

addDependent: addDependent: removeDependent: removeDependent: changed:changed:

ValueHolderValueHoldervalue:value:valuevalue

TextViewTextView

update:update:

observer/observer/dependentdependent

modelmodel

Observer Pattern:

Registrationsubject addDependent: observer

Notificationself changed. self changed: #value

Updatedefine update: aSymbol

Notification

Object notifies dependents when information changes by sending itself a #changed message.

changed: anArg

self dependents

do: [:each | each update: anArg]

Problem

A man and dog are in the room. When the dog wants to go out, he barks. When the man hears the dog barking, he opens the door. When the dog wants to go out and the door is open, he leaves.

Basic classes

Dog

bark / move

Person

Door

open / close / isOpen

Object

addDependent:

changed:

update:

Collaborations

PersonDoor

openclose

Dog

bark listenwatch

Dynamic ModelRecord order of events, interaction between objects.Record order of events, interaction between objects.

DogDog PersonPerson DoorDoor

Sequence diagramSequence diagram

barkbarkopenopennotifynotify

go thru doorgo thru door

notifynotifycloseclose

registerregisterregisterregister

unregisterunregister

notifynotify

A Script

| person door dog |door := Door new close.dog := Dog new.dog door: door.person := Person new.person door: door; dog: dog.dog bark.

Dooropened <Boolean>

open

opened := true.

self changed: #open

Door

close

opened := false.

self changed: #close

isOpen

^opened

DogcurrentState :: #sleeping, #waiting, #outside

bark

currentState := #waiting.

self changed: #bark

door: aDoor

door := aDoor.

door addDependent: self

Dog

goOut

currentState := #outside.

door removeDependent: self.

self changed: #move

Dogupdate: aSymbol

(currentState == #waiting) & (aSymbol == #open)

ifTrue: [self goOut ]

Person

dog: aDog

dog := aDog.

dog addDependent: self

Person

update: aSymbol

aSymbol == #bark

ifTrue: [door open].

aSymbol == #move

ifTrue: [door close]

Watcher

instance variable: name <String>update: aSymbol

Transcript show: subjectName; show: ' '; show: aSymbol; cr

name: aStringname := aString

| person door dog |door := Door new close.door addDependent:

(Watcher new name: 'door').dog := Dog new.door addDependent: dog.dog addDependent:

(Watcher new name: 'Fido').person := Person new.person door: door; dog: dog.dog bark.

Improvements

Creating method

(have class method return initialized object)

Compose method

(Watcher on: door name: 'door')

(door watcherNamed: 'door')

Model and Memory Management

Dog allInstancesreports a lot of dogs! Garbage

collection doesn't help.Object uses a global dictionary to store

dependents. Subject must "release" its observers/dependents.

Make Dog a subclass of Model

Model uses an instance variable to store dependents. It does not have to release its observers.

Subclasses of Model cause less problems with garbage collection.

Class that has dependents should be subclass of Model.

If you are not using Model then after the script says

dog bark.

add the messages

dog release.

door release.

person release

Advantage of Observer Pattern

Easy to add new observers.

Coupling between observer and subject is abstract.

Disadvantage of Observer Pattern

Often hard to understand relationships between objects in system.

Sometimes inefficient.

Adding New Observer

Suppose room also has a bird, which is usually in a cage.

If bird is not in cage and door opens, bird flies out.

Bird

update: aSymbol

(aSymbol == #open) &

(self isCaged not)

ifTrue: [self flyOut]

Script must now create a bird and make it depend on the door.

Summary

Observer is an important patternUsed in a UI to make reusable componentsReduces coupling by increasing abstractionAbstraction makes programs easier to change, harder to understandOften requires a “script” to set up dependencies