620 likes | 1.27k Views
A Smalltalk Patterns Safari Brian Foote The Refactory, Inc. Why Patterns? What’s New Here is that Nothing is New Here Patterns are about what works Patterns give us a way to talk about what works Patterns distill experience Patterns give us a pithy design vocabulary
E N D
A Smalltalk Patterns Safari Brian Foote The Refactory, Inc. Smalltalk Patterns Safari
Why Patterns? • What’s New Here is that Nothing is New Here • Patterns are about what works • Patterns give us a way to talk about what works • Patterns distill experience • Patterns give us a pithy design vocabulary Smalltalk Patterns Safari
Alexander on Patterns • Patterns in solutions come from patterns in problems. • "A pattern is a solution to a problem in a context." • "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." • Christopher Alexander -- A Pattern Language Smalltalk Patterns Safari
Why Patterns in the Wild? • Learn where to look • Learn how to spot ‘em and recognize ‘em • See how they evolve • Appreciate their history, and our history • Understand their ecosystem and interdependence • Helps us discern and discover new ones Smalltalk Patterns Safari
The Gang of Four:The Essential Field Guide • Design Patterns: Elements of Reusable Object-Oriented Software • Erich Gamma, Richard Helm, Ralph Johnson, and John Vlissides • Addison Wesley, 1995 • A landmark book that changed the way programmers think about building object-oriented programs Smalltalk Patterns Safari
Dr. Johnson, I presume? • Great explorers, like Livingstone and Johnson neither necessarily create nor invent, nor, do they even always “discover” • Often, their greatest skill is communication... Smalltalk Patterns Safari
Your Guide • Over Twenty Years in the Bush... • Stalking Smalltalk since ‘81… or ‘85… Patterns? • An long-time associate of Dr. Johnson... Smalltalk Patterns Safari
Field Guides (cont.) • The Design Patterns Smalltalk Companion • Alpert, Brown, and Woolf • Addison Wesley, 1998 • Pattern-Oriented Software Architecture • Buschmann, Meunier, Rohnert, Sommerlad, and Stahl • Wiley, 1996 • The Pattern Languages of Program Design Series • Volumes 1-4 • Addison Wesley, 1995-2000 Smalltalk Patterns Safari
VisualWorks*The Image: A Virtual Veldt • The Cradle of Object-OrientedArchitecture • An Olduvai Gorge Teeming with Patterns Smalltalk Patterns Safari
GoF Design Patterns • Creational patterns • Abstract Factory • Builder • Factory Method • Prototype • Singleton • Structural patterns • Adapter • Bridge • Composite • Decorator • Facade • Flyweight • Proxy • Behavioral Patterns • Chain of Responsibility • Command • Interpreter • Iterator • Mediator • Memento • Observer • State • Strategy • Template Method • Visitor Smalltalk Patterns Safari
The Big Five • Lion • Leopard • Elephant • Buffalo • Rhino • Composite • Proxy • Strategy • Observer • Visitor Smalltalk Patterns Safari
Objects within Objects Smalltalk Patterns Safari
Composite • Context: • Developing OO software • Problem: • 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 same Smalltalk Patterns Safari
Composite • Idea: make abstract "component" class. • Alternative 1: every component has a (possibly empty) set of components. Component Children Chapter Paragraph ... Problem: many components have no components Smalltalk Patterns Safari
Composite Component Container Children Leaf Composite • Composite and Component have the exact same interface. • • interface for enumerating children • • Component implements Children() by returning empty set • • interface for adding/removing children? Smalltalk Patterns Safari
Composite Pattern Component Container Children Leaf Composite • Composite and Component have the exact same interface. • • interface for enumerating children • • Component implements Children() by returning empty set • • interface for adding/removing children? Smalltalk Patterns Safari
Two Design Alternatives • Component does not know what it is a part of. • Component can be in many composite. • Component can be accessed only through composite. • Component knows what it is a part of. • Component can be in only one composite. • Component can be accessed directly. Smalltalk Patterns Safari
Component Knows its Composite • Rules 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. Smalltalk Patterns Safari
Ensuring Consistency • The 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. • Smalltalk does not enforce private methods. Smalltalk Patterns Safari
Example: Equipment Equipment weight • weight • | total | • total := 0. • self childrenDo: [:each | total := total + each weight]. • ^total cost ... FloppyDisk CompositeEq. Smalltalk Patterns Safari
VisualComponent>>add: Smalltalk Patterns Safari
Composite Pattern in VisualWorks VisualComponent Children • Most operations in CompositePart simply iterate over the children and repeat the operation on them. VisualPart ComposedText Container CompositePart ListView Smalltalk Patterns Safari
CompositePart • addComponent: aVisualComponent • self isOpen • ifTrue: [ ... ] • ifFalse: [components addLast: aVisualComponent. • aVisualComponent container: self] • displayOn: aGraphicsContext • "Display each of the receiver's components." • | clipBox | • clipBox := aGraphicsContext clippingBounds. • components do: • [:component | • (component intersects: clipBox) • ifTrue: [component displayOn: aGraphicsContext copy]] Smalltalk Patterns Safari
Summary of Composite • Composite is a kind of Component • Permits arbitrary hierarchies • Add/remove Component from Composite • Operations on Composite iterate over Components Smalltalk Patterns Safari
Template Method • As plentiful as sawgrass... • Often associated with scavengers • e.g. printOn: aString Smalltalk Patterns Safari
Factory Method • Plentiful in the image... • View defaultControllerClass • UILookPolicy • XxxClass methods Smalltalk Patterns Safari
Abstract Factory Smalltalk Patterns Safari
Builder • ClassBuilder • UI Builders Smalltalk Patterns Safari
Prototype • This isn’t Self, after all... • VisualWorks TextAttributes • Look for copy • Thinglab, Morphic... Smalltalk Patterns Safari
Singleton • All the Metaclasses... • ProcessScheduler • SourceFileManager • true, false, nil Smalltalk Patterns Safari
Strategy • Sundry Policies... Smalltalk Patterns Safari
Observer Pattern • Intent: Define a one-to-many dependency between objects so that when one object changes state, all its dependents are notified and updated automatically. observer/dependent Observer Update Subject AddDependent RemoveDependent Changed LineFigure Update endPoint RectangleFigure Smalltalk Patterns Safari
Iterator • Provide a way to access the elements of an aggregate object sequentially without exposing its underlying implementation. Iterator Aggregate First() Next() IsDone() CurrentItem() CreateIterator() ConcreteAggregate ConcreteIterator CreateIterator() Smalltalk Patterns Safari
Iterator in Smalltalk • 1) Internal iterator - iterate inside the Iterator • easy to use, not as powerful as external iterator • works well because of blocks • employees do: [:each | each name printOn: aStream] • 2) Combine Next() and CurrentItem() (Smalltalk Stream) • employeeStream := GeneralMotors employeeStream. • [employeeStream atEnd] • whileFalse: • [employeeStream next name printOn: aStream] Smalltalk Patterns Safari
Proxy • Provide a surrogate or placeholder for another object to control access to it • represent an object in a remote address space • create expensive objects on demand • check access rights • Proxy has same interface as “real subject”, and forwards operations to it Smalltalk Patterns Safari
Proxy Subject Client request ... realSubject Proxy RealSubject request request realSubject request Smalltalk Patterns Safari
Proxy • Remote proxy - first package arguments, then make remote procedure call. • Virtual proxy - compute objects, then forward request. • Protection proxy - check access rights, then forward request. Smalltalk Patterns Safari
Creating an Orphan nil subclass: #Future instanceVariableNames: ‘semaphore ' classVariableNames: ‘ ' poolDictionaries: ' ' category: ‘Reflection-Examples’ In VisualWorks, ClassBuilder does the rest. Default implementations of doesNotUnderstand: and class are provided. Smalltalk Patterns Safari
Locating Orphans allBehaviorsDo: aBlock "Evaluate the argument, aBlock, for each kind of Behavior in the system (that is, Object and its subclasses, plus other classes that have no superclass)." Class rootsOfTheWorld do: [:cls | aBlock value: cls. cls allSubclassesDo: aBlock] Smalltalk Patterns Safari
Terminology and Taxonomy • Is this a Wildebeest? • A Gnu? • Class: MammaliaOrder: ArtiodactylaFamily: BovidaeGenus species:Connochaetes (flowing beard) taurinus (like a bull) albojubatus (white mane) Smalltalk Patterns Safari
Decorator • Object () • VisualComponent () • VisualPart () • Wrapper () • GeometricWrapper () • FillingWrapper () • StrokingWrapper () • GraphicsAttributesWrapper () • PassivityWrapper ('controlActive') • ReversingWrapper () • StrikeOutWrapper () • ScalingWrapper () • TranslatingWrapper () • LayoutWrapper () • BoundedWrapper () • BorderedWrapper () • MenuBarWrapper () • BoundingWrapper () • ScrollWrapper () • DataSetScrollWrapper () • SlaveScrollWrapper () • WidgetStateWrapper () • WidgetWrapper () • SpecWrapper () Smalltalk Patterns Safari
Adaptor • Aspect Adaptor • Pluggable Adaptor Smalltalk Patterns Safari
Flyweight • Character Smalltalk Patterns Safari
Chain of Responsibility • VisualPart Smalltalk Patterns Safari
Command • MenuItem • Blocks are often used instead in Smalltalk, so this pattern is not as common in its pure form in this environment... Smalltalk Patterns Safari
Interpreter • The WindowSpec Walker • Though it’s not clear how to classify this… • The simulator? Smalltalk Patterns Safari
Observer Smalltalk Patterns Safari
Parse Tree Smalltalk Patterns Safari
Visitor • ProgramNodeEnumerator • This class provides a framework for recursively processing a program node tree. Program nodes of type <NodeType> should implement • nodeDo: anEnumerator • ^anEnumerator do<NodeType>: self ...arguments... • by analogy with the ProgramNodeBuilder messages • new<NodeType>[arguments] • The old node is the first argument, so that enumerators can preserve the comment and source information if they wish. • To rebuild each non-leaf node, the enumerator sends the message • self doNode: <argument> • which is implemented by default as • doNode: aNode • ^aNode nodeDo: self Smalltalk Patterns Safari
Visitor • ProgramNodeEnumerator • Subclasses must implement the following messages: • enumerating-non-leaves • doAssignment:variable:value: • doBlock:arguments:body: • doCascade:receiver:messages: • doMessage:receiver:selector:arguments: • doMethod:selector:primitive:block: • doParameter:variable:type: • doReturn:value: • doSequence:temporaries:statements: • enumerating-leaves • doLiteral:value: • doVariable:name: Smalltalk Patterns Safari