CSC 7322 Object Oriented Development J Paul Gibson
CSC 7322 : Object Oriented Development J Paul Gibson, A 207 paul. gibson@int-edu. eu http: //www-public. it-sudparis. eu/~gibson/Teaching/CSC 7322/ Design Patterns Revisited …/~gibson/Teaching/CSC 7322/L 13 -Design. Patterns-2. pdf 2013: J Paul Gibson TSP: Software Engineering CSC 7322/Design. Patterns. 1
Learning by PBL – the patterns selected 1. Singleton - creational 2. Iterator – behavioural 3. Visitor – behavioural 4. Proxy - structural 5. Factory - creational 6. Decorator – structural 7. Facade - structural 8. Adapter - structural 9. Chain Of Responsibility - behavioural 10. MVC – a composite pattern (Strategy, Observer, Composite) 2013: J Paul Gibson TSP: Software Engineering CSC 7322/Design. Patterns. 2
Decorator Pattern See - http: //sourcemaking. com/design_patterns/decorator • Intent • Attach additional responsibilities to an object dynamically. Decorators provide a flexible alternative to subclassing for extending functionality. • Client-specified embellishment of a core object by recursively wrapping it. • Wrapping a gift, putting it in a box, and wrapping the box. • Problem • You want to add behavior or state to individual objects at run-time. • Inheritance is not feasible because it is static and applies to an entire class. 2013: J Paul Gibson TSP: Software Engineering CSC 7322/Design. Patterns. 3
Decorator Pattern See - http: //sourcemaking. com/design_patterns/decorator Relation to other patterns Adapter provides a different interface to its subject. Proxy provides the same interface. Decorator provides an enhanced interface. Adapter changes an object’s interface, Decorator enhances an object’s responsibilities. Decorator is thus more transparent to the client. As a consequence, Decorator supports recursive composition, which isn’t possible with pure Adapters. Composite and Decorator have similar structure diagrams, reflecting the fact that both rely on recursive composition to organize an open-ended number of objects. A Decorator can be viewed as a degenerate Composite with only one component. However, a Decorator adds additional responsibilities - it isn’t intended for object aggregation. 2013: J Paul Gibson TSP: Software Engineering CSC 7322/Design. Patterns. 4
Decorator Pattern See - http: //sourcemaking. com/design_patterns/decorator Relation to other patterns Decorator is designed to let you add responsibilities to objects without subclassing. Composite’s focus is not on embellishment but on representation. These intents are distinct but complementary. Consequently, Composite and Decorator are often used in concert. Composite could use Chain of Responsibility to let components access global properties through their parent. It could also use Decorator to override these properties on parts of the composition. Decorator and Proxy have different purposes but similar structures. Both describe how to provide a level of indirection to another object, and the implementations keep a reference to the object to which they forward requests. Decorator lets you change the skin of an object. Strategy lets you change the guts. Most of these patterns use a form of delegation (which is not usually considered a pattern in its own right) 2013: J Paul Gibson TSP: Software Engineering CSC 7322/Design. Patterns. 5
Decorator Pattern Class Diagram UML The following diagram shows structure of typical decorator pattern, the diagram was taken dofactory. com 2013: J Paul Gibson TSP: Software Engineering CSC 7322/Design. Patterns. 6
Decorator Pattern Class Diagram UML The following diagram shows a concrete example of an Account (from http: //blog. decarufel. net/2009/09/using-decorator-or-wrapper-design. html) 2013: J Paul Gibson TSP: Software Engineering CSC 7322/Design. Patterns. 7
Decorator Pattern Sequence Diagram UML The following diagram shows a concrete example of Account dynamic behaviour 2013: J Paul Gibson TSP: Software Engineering CSC 7322/Design. Patterns. 8
Decorator Pattern Sequence Diagram UML: explanation 1. 2. 3. 4. 5. 6. 7. Call Bank. Create. Account. The Bank instantiates an Account class. The Bank creates an Account. Deposit. Validator and wrap Account with it The Bank return an instance of IAccount. Deposit is called on IAccount which is an instance of Account. Deposit. Validator calls Validate Account. Deposit. Validator call Get. Validations to retrieve the list of validation to evaluate 8. An Amount. Greater. Tha. Zero. Validation is created 9. Is. Valid returns true 10. Account. Deposit. Validator call base Deposit method 11. Balance value is updated 2013: J Paul Gibson TSP: Software Engineering CSC 7322/Design. Patterns. 9
Decorator Problem : The classic Christmas tree (revisited) Problem: Examine the Java code in the package p_decorator in the folder Patterns (~gibson/Teaching/CSC 7322/Code/Decorator. zip) 2013: J Paul Gibson TSP: Software Engineering CSC 7322/Design. Patterns. 10
Decorator – Christmas Tree package specifications; public interface Branch. Of. Tree. Specification { public void animate(); public String get. Decorations(); } 2013: J Paul Gibson TSP: Software Engineering CSC 7322/Design. Patterns. 11
Decorator – Christmas Tree package specifications; public abstract class Branch. Decorator. Specifiation implements Branch. Of. Tree. Specification{ protected Branch. Of. Tree. Specification decorated. Branch; public Branch. Decorator. Specifiation(Branch. Of. Tree. Specification branch. To. Decorate){ decorated. Branch= branch. To. Decorate; } public void animate(){decorated. Branch. animate(); } } 2013: J Paul Gibson TSP: Software Engineering CSC 7322/Design. Patterns. 12
Decorator - Christmas Tree package models; import specifications. Branch. Of. Tree. Specification; public class Undecorated. Branch implements Branch. Of. Tree. Specification{ public void animate(){} public String get. Decorations(){ return ""; } } 2013: J Paul Gibson TSP: Software Engineering CSC 7322/Design. Patterns. 13
Decorator - Christmas Tree package models; import specifications. Branch. Decorator. Specification; import specifications. Branch. Of. Tree. Specification; public class Ball. Decorator extends Branch. Decorator. Specification{ boolean spinning; public Ball. Decorator(Branch. Of. Tree. Specification branch. Of. Tree){ super(branch. Of. Tree); spinning = true; } public String get. Decorations(){ String str = decorated. Branch. get. Decorations(); if (spinning) str = str +" Spinning"; str = str+ " Ball. "; return str; } public void animate(){ decorated. Branch. animate(); spinning = !spinning; } } 2013: J Paul Gibson TSP: Software Engineering CSC 7322/Design. Patterns. 14
Decorator– Christmas Tree package models; import specifications. Branch. Decorator. Specifiation; import specifications. Branch. Of. Tree. Specification; public class Lights. Decorator extends Branch. Decorator. Specifiation{ String colour; public Lights. Decorator(Branch. Of. Tree. Specification branch. Of. Tree){ super(branch. Of. Tree); colour = "red"; } public String get. Decorations(){ String str = decorated. Branch. get. Decorations(); str =str+ " colour = "+colour; return str; } public void animate(){ decorated. Branch. animate(); if (colour. equals("red")) colour ="white"; else if (colour. equals("white")) colour ="blue"; else colour = "red"; } } 2013: J Paul Gibson TSP: Software Engineering CSC 7322/Design. Patterns. 15
Decorator– Christmas Tree public class Test. Ball. Decorator { public static void main (String [] args){ Branch. Of. Tree. Specification plain. Branch = new Undecorated. Branch(); Branch. Of. Tree. Specification decorated. Branch = new Ball. Decorator( plain. Branch); Branch. Of. Tree. Specification re. Decorated. Branch = new Ball. Decorator( plain. Branch)); System. out. println("plain. Branch. get. Decorations() ="+plain. Branch. get. Decorations()); System. out. println("decorated. Branch. get. Decorations() ="+decorated. Branch. get. Decorations()); System. out. println("re. Decorated. Branch. get. Decorations() =" +re. Decorated. Branch. get. Decorations()); plain. Branch. animate(); System. out. println("plain. Branch. animate. get. Decorations() ="+plain. Branch. get. Decorations()); decorated. Branch. animate(); System. out. println("decorated. Branch. animate. get. Decorations() ="+decorated. Branch. get. Decorations()); re. Decorated. Branch. animate(); System. out. println("re. Decorated. Branch. animate. get. Decorations() =" +re. Decorated. Branch. get. Decorations()); } } 2013: J Paul Gibson TSP: Software Engineering CSC 7322/Design. Patterns. 16
Decorator - Christmas Tree 2013: J Paul Gibson TSP: Software Engineering CSC 7322/Design. Patterns. 17
Decorator – Christmas Tree TO DO: • Test Lights Decoration • Test Lights with Balls Decoration • Add new Decoration (Stars, eg) • Test 3 Decorations together Create XMAS tree with 4 branches: • 2 Lights and 2 Balls • 2 Lights and 3 Stars • 2 Stars and 3 Balls • 2 Lights and 2 Stars and 2 Balls PROBLEM: Ensure that the state of decorations on the same branch of tree is coordinated (but not necessarily on different branches) OPTION: Maximum number of decorations on any branch is 6 2013: J Paul Gibson TSP: Software Engineering CSC 7322/Design. Patterns. 18
Decorator– Christmas Tree What to learn from the problem: If you really need multiple instances of same decoration then this pattern is probably not correct. The following 4 sentences seem equivalent but may lead to different designs/implementations: The branch « is a » branch with lights and stars The branch « is a » branch with lights and « is a » branch with stars The branch « has » lights and the branch « has » stars Knowing which design is best depends on knowing precisely what is the intended/required behaviour. The decorator is not intended to allow statements like: The branch « is a » branch with lights and « is a » branch with lights 2013: J Paul Gibson TSP: Software Engineering CSC 7322/Design. Patterns. 19
Decorator – Christmas Tree Solving the problem: If we really need multiple decorations of the same type on a single branch do not use the decorator pattern in this way We should fix the decorator pattern so that decorating a branch with ball behaviour that has already been decorated with ball behaviour is either: • Handled by an exception, or • Ignored TO DO – implement one of these solutions, and retest the new behaviour NOTE: As requirements change you may be tempted to compromise your system by holding on to a pattern which is no longer appropriate 2013: J Paul Gibson TSP: Software Engineering CSC 7322/Design. Patterns. 20
Facade versus Adapter Intuitively, what are the differences? 2013: J Paul Gibson TSP: Software Engineering CSC 7322/Design. Patterns. 21
Facade versus Adapter 2013: J Paul Gibson TSP: Software Engineering CSC 7322/Design. Patterns. 22
Facade versus Adapter 2013: J Paul Gibson TSP: Software Engineering CSC 7322/Design. Patterns. 23
Facade - provides a unified interface to a set of interfaces in a subsystem Identify a simpler, unified interface for the subsystem/component. Design a ‘wrapper’ class that encapsulates the subsystem. The facade/wrapper captures the complexity and collaborations of the component, and delegates to the appropriate methods. The client uses (is coupled to) the Facade only. Facade defines a new interface, whereas Adapter uses an old interface. Remember that Adapter makes two existing interfaces work together as opposed to defining an entirely new one. 2013: J Paul Gibson TSP: Software Engineering CSC 7322/Design. Patterns. 24
Adapter - lets classes work together that couldn’t otherwise because of incompatible interfaces Identify the players: the component(s) that want to be accommodated (i. e. the client), and the component that needs to adapt (i. e. the adaptee). Identify the interface that the client requires. Design a “wrapper” class that can “impedance match” the adaptee to the client. The adapter/wrapper class “has a” instance of the adaptee class. The adapter/wrapper class “maps” the client interface to the adaptee interface. The client uses (is coupled to) the new interface 2013: J Paul Gibson TSP: Software Engineering CSC 7322/Design. Patterns. 25
Realation to Other Design Patterns Adapter and Facade are both wrappers; but they are different kinds of wrappers. The intent of Facade is to produce a simpler interface, and the intent of Adapter is to design to an existing interface. While Facade routinely wraps multiple objects and Adapter wraps a single object; Facade could front-end a single complex object and Adapter could wrap several legacy objects. Adapter makes things work after they’re designed; Bridge makes them work before they are. Bridge is designed up-front to let the abstraction and the implementation vary independently. Adapter is retrofitted to make unrelated classes work together. Adapter provides a different interface to its subject. Proxy provides the same interface. Decorator provides an enhanced interface. 2013: J Paul Gibson TSP: Software Engineering CSC 7322/Design. Patterns. 26
The Rectangle Problem A legacy Rectangle component’s display() method expects to receive “x, y, w, h” parameters. But the client wants to pass “upper left x and y” and “lower right x and y”. This mismatch can be reconciled by using a design pattern. Question: is this suitable for an adapter or a facade (or something else) Draw the UML design and implement in Java 2013: J Paul Gibson TSP: Software Engineering CSC 7322/Design. Patterns. 27
Chain of responsibility Avoid 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. 2013: J Paul Gibson TSP: Software Engineering CSC 7322/Design. Patterns. 28
Chain of responsibility Note: Chain of Responsibility can use Command to represent requests as objects THIS MAY BE USEFUL IN YOUR OO PROJECT 2013: J Paul Gibson TSP: Software Engineering CSC 7322/Design. Patterns. 29
- Slides: 29