Unformatted text preview:

PatternsChristopher Alexander -- A Pattern LanguageDesign Patterns: Elements of Reusable Object-Oriented SoftwareCompositeForcesSlide 6Composite PatternTwo design alternatives for Part-ofPart-ofEnsuring ConsistencyPowerPoint PresentationSlide 12Example: Views and FiguresComposite Pattern in VisualWorksCompositePartSlide 16Observer PatternSlide 18Observer Pattern:NotificationProblemBasic classesCollaborationsDynamic ModelA ScriptDoorSlide 27DogSlide 29Slide 30PersonSlide 32WatcherSlide 34ImprovementsModel and Memory ManagementMake Dog a subclass of ModelSlide 38Advantage of Observer PatternDisadvantage of Observer PatternAdding New ObserverBirdSummarySlide 44PatternsAll designers use patterns.Patterns in solutions come from patterns in problems."A pattern is a solution to a problem in a context."Christopher Alexander -- A Pattern Language"Each pattern describes a problem which occurs over and over again in our environment, and then describes the core of the solution to that problem, in such a way that you can use this solution a million times over, without ever doing it the same way twice."Design Patterns: Elements of Reusable Object-Oriented SoftwareErich Gamma, Richard Helm, Ralph Johnson, John VlissidesAddison-Wesley 199523 object-oriented patternsCompositeContext:Developing OO softwareProblem:Complex part-whole hierarchy has lots of similar classes.Example: document, chapter, section, paragraph.Forces• simplicity -- treat composition of parts like a part• power -- create new kind of part by composing existing ones• safety -- no special cases, treat everything the sameCompositeIdea: make abstract "component" class.Alternative 1: every component has a (possibly empty) set of components.Problem: many components have no components.ComponentChildrenParagraphChapter...*Composite PatternComponentcontainerchildrenDo:CompositeLeafComposite and Composite and Component have the Component have the exact sameexact same interface. interface.• • enumerating childrenenumerating children• • childrenDo: for childrenDo: for Component does Component does nothingnothing• • only Composite adds only Composite adds removes children.removes children.*Two design alternatives for Part-ofComponent does not know what it is a part ofComponent can be in many composite.Component can be accessed only through composite.Component knows what it is a part ofComponent can be in only one composite.Component can be accessed directly.:Part-ofRules when component knows its single composite.A is a part of B if and only if B is the composite of A.Duplicating information is dangerous!Problem: how to ensure that pointers from components to composite and composite to components are consistent.Ensuring ConsistencyThe public operations on components and composites are:• Composite can enumerate components.• Component knows its container.• Add/remove a component to/from the composite.The operation to add a component to a composite updates the container of the component. There should be no other way to change the container of a component.In C++, make component friend of composite.Smalltalk does not enforce private methods.privatecontainer: anObjectcontainer := anObjectaccessingaddComponent: aComponentcomponents add: aComponentaComponent container: selfExample: Views and FiguresBig window can contain smaller windows.Composite Pattern in VisualWorksVisualPartContainerCompositePartVisualComponentChildrenComposedTextListViewMost operations in CompositePart iterate over the children and repeat the operation on them.*CompositePartaddComponent: aVisualComponentself isOpenifTrue: [ ... ]ifFalse: [components addLast: aVisualComponent.aVisualComponent container: self]displayOn: aContext"Display each component."| clipBox |clipBox := aContext clippingBounds.components do:[:each | (each intersects: clipBox)ifTrue: [each displayOn: aContext copy]]Observer PatternDependence 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 PatternObserverObserverupdate:update:SubjectSubjectaddDependent: addDependent: removeDependent: removeDependent: changed:changed:ValueHolderValueHoldervalue:value:valuevalueTextViewTextViewupdate:update:observer/observer/dependentdependentmodelmodelObserver Pattern: Registrationsubject addDependent: observerNotificationself changed. self changed: #valueUpdatedefine update: aSymbolNotificationObject notifies dependents when information changes by sending itself a #changed message.changed: anArgself dependents do: [:each | each update: anArg]ProblemA 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 classesDogbark / movePersonDooropen / close / isOpenObjectaddDependent:changed:update:CollaborationsPersonDooropencloseDogbarklistenwatchDynamic ModelRecord order of events, interaction between objects.Record order of events, interaction between objects.DogDogPersonPersonDoorDoorSequence diagramSequence diagrambarkbarkopenopennotifynotifygo thru doorgo thru doornotifynotifyclosecloseregisterregisterregisterregisterunregisterunregisternotifynotifyA 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>openopened := true.self changed: #openDoorcloseopened := false.self changed: #closeisOpen^openedDogcurrentState :: #sleeping, #waiting, #outsidebarkcurrentState := #waiting.self changed: #barkdoor: aDoordoor := aDoor.door addDependent: selfDoggoOutcurrentState := #outside.door removeDependent: self. self changed: #moveDogupdate: aSymbol(currentState == #waiting) & (aSymbol == #open)ifTrue: [self goOut ]Persondog: aDogdog := aDog.dog addDependent: selfPersonupdate: aSymbolaSymbol == #bark ifTrue: [door open].aSymbol == #move ifTrue: [door close]Watcherinstance variable: name <String>update: aSymbolTranscript show: subjectName; show: ' '; show: aSymbol; crname: 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


View Full Document

UIUC CS 598 - Patterns

Download Patterns
Our administrator received your request to download this document. We will send you the file to your email shortly.
Loading Unlocking...
Login

Join to view Patterns and access 3M+ class-specific study document.

or
We will never post anything without your permission.
Don't have an account?
Sign Up

Join to view Patterns 2 2 and access 3M+ class-specific study document.

or

By creating an account you agree to our Privacy Policy and Terms Of Use

Already a member?