Design Patterns in SmalltalkWe talked about ...IteratorComparing two collectionsSlide 5ProxySlide 7Implementing Proxy with doesNotUnderstand:BridgeFlyweightFlyweights for TextSlide 12Flyweight for CADSlide 14Flyweight as a compound patternChain of ResponsibilitySlide 17Slide 18MementoSlide 20Slide 21Slide 22Patterns Protect from ChangePatterns lead to standard interfacesSmalltalk features impact patternsPatterns and refactoringCommandRefactoring to CommandCompositeRefactoring to a CompositeFaçadeDesign patterns and refactoringDesign Pattern summaryDesign Patterns in SmalltalkInfluenced by programming languageLarge-scale refactoringsWe talked about ...Template MethodState, Strategy, Observer, Mediator, FacadeCommand, Interpreter, VisitorAdapter, Composite, DecoratorFactory Method, Abstract Factory, Builder, Prototype, SingletonIteratorInternal iterator vs external iteratorInternal iterators depend on blocksInternal iterators simplerExternal iterators more powerfulComparing two collections= anObject| first second |self size = anObject size ifFalse: [^false].first := ReadStream on: self.second := ReadStream on: anObject.[first atEnd | second atEnd] whileFalse:[first next = second next ifFalse: [^false]].^first atEnd & second atEndIteratorProvide a way to access the elements of an aggregate object sequentially without exposing its underlying implementation.ConcreteIteratorIteratorFirst()Next()IsDone()CurrentItem()ConcreteAggregateCreateIterator()AggregateCreateIterator()ProxyProvide a surrogate or placeholder for another object to control access to itrepresent an object in a remote address spacecreate expensive objects on demandcheck access rights Proxy has same interface as “real subject”, and forwards operations to itProxySubjectRequestClientProxyRequestrealSubjectRealSubjectRequestImplementing Proxy with doesNotUnderstand:When an object does not understand a message, the message gets converted into doesNotUnderstand: message with the original message as an argumentDefault version of doesNotUnderstand: pops up a debuggerProxy can override doesNotUnderstand:BridgeDecouple an abstraction from its implementation so that the two can vary independently.ImplementorConcreteImp2AbstractionConcreteImp1FlyweightUse sharing to support large numbers of objects efficiently.Separate intrinsic state (state stored in flyweight) from extrinsic state (state passed in as part of context). Minimize extrinsic state. Share flyweights that have the same intrinsic state.Usually requires a factory that detects whether a flyweight exists with a particular intrinsic state and returns it.Flyweights for TextcolumnrowrowrowT h i s i s a s e n t e n c eT h i s a s e n t cFlyweight poolClient of flyweight,which holds context.Context is location.FlyweightFlyweightFactoryGetFlyWeight(key)Flyweight intrinsicOperation(extrinsic)flyweightpoolFlyweight class is usually abstract, with concrete subclasses that define the intrinsic state.Flyweight for CADA VLSI design system must model millions of transistors.This is only possible by sharing structure. Most transistors are part of larger structures (registers, NAND gates, RAM) that designers prefer to think about. Each kind of structure is called a cell.Each cell is interconnected with other cells.Context is location and interconnections.Flyweight for CADTransistorsizeDisplay(loc,connects)CellDisplay(loc,connects)flyweightpoolCompositeCellports, locationsDisplay(loc,connects)CellFactoryGetCell(key)Register(key,Cell)Flyweight as a compound pattern1) Recycling Factory (generalization of Singleton)2) Value Object - immutable objects3) Normalized Object - Separating intrinsic from extrinsicChain of ResponsibilityAvoid coupling the sender of a request to its receiver by giving more than one object a chance to handle the request. Chain the receiving objects and pass the request along the chain until an object handles it.Examples:“inheriting” color from carevent handlers in GUIChain of ResponsibilityHandlerHandleRequest()ConcreteHandler2HandleRequest()ConcreteHandler1HandleRequest()ClientChain of ResponsibilityUsually mixed with other patterns• Composite often has Chain of Responsibility up the tree.• Sometimes request is encoded as a Command• Sometimes request sent to StrategyMementoWithout violating encapsulation, capture and externalize an object’s internal state so that the object can be restored to this state later.MementoGetStateSetStatestateOriginatorSet(Memento)CreateMementostateOriginatorreturn new Memento(state)state = m->GetState()MementoUndo is not enough in the presence of a constraint system.Must go back to same state, not just reverse operation.MementoA C A B C C B A A CX Z X Y Y X X X Z Translator isa state machineinput documentChange part of inputand recompute output.output documentA BProblem: Large structured documents are stored in one form and translated to another form to be printed. How can a small change in the input be converted into a change in the output without retranslating the entire input?MementoFor each input symbol, keep a memento of the translator and the output for that input symbol. Recompute the output until the translator is back in the same state.I S T O P Q R S S S TX Z X Y Y X X X Z next stateA C A B C C B A A CA Boutputinitial stateinputPatterns Protect from ChangeRule: if something is going to change, make it an object.Strategy: make algorithm an object so it can changeState: make state-dependent behavior an object so it can changeIterator: make the way you iterate over an aggregate an object so it can changeFacade: make a subsystem an object so it can changeMediator: make the way objects interact an object so it can changeFactory: make the classes of your products an object so it can changePatterns lead to standard interfacesDecorator, Composite, ProxyIntroduce new objects with same interfaces as old but that add a feature / represent a group / represent a remote objectAdapterFacadeSmalltalk features impact patternsIterator – blocksProxy – doesNotUnderstand:Command – blocks, perform:Prototype – classes as objectsBridge – dynamic typing?Patterns and refactoringCan think of any design pattern as a “big refactoring”Introduce design patterns when you know you need them, not when you think you might need themRefactoring to Patterns by Joshua
View Full Document