More OOP Design Patterns Chapter 15 The Idea of a Design Pattern A design pattern is simply a standard solution for solving a common problem. • This solution is standard because all programmers are trying to balance a common set of forces that occur when we try to solve that class of problems. Decorator Pattern • Decorator design pattern solves the problem of adding a behavior to every class in a hierarchy. • This is a remarkably common problem. Among the forces that a decorator balances are: – Programmers should not have to write the same code to do exactly the same thing in two different places. – Client code should not have to know that it is using an instance of a particular class. If it does, then we have to write new client code each time. • The solution is to use a common interface for all classes, and to write a class that delegates the real work to an instance that implements the same interface. MVC Design Patterns • Model-View-Controller (MVC) • A collection of simpler patterns that are incredibly useful. • Using MVC, you think of the application in terms of these three modules – Model : The core of the application. This maintains the state and data that the application represents. When significant changes occur in the model, it notifies all of its views – Controller : The user interface presented to the user to manipulate the application. – View : The user interface which displays information about the model to the user. Any object that needs information about the model needs to be a registered view with the model. MVC Design Patterns • MVC decouples views and model by establishing a subscribe/notify protocol which is an example of the Observer design pattern. Observer Design Pattern: – Problem: How do you allow two or more independent and loosely coupled objects to change in synchrony with each other? – Solution: Maintain a list of objects that are tied, or dependent, on another object. When the target object changes, the dependents, or observers, are notified that they should update themselves. Observer Design Pattern • Examples: – MVC Heart Beat example – User interface components that permit interaction (buttons, scrollbar, etc.) maintain a collection of listener objects. • We can dynamically add or remove listener objects as long as they satisfy an interface. • When the state of the GUI component changes, each of the listeners is notified of a change. Observer Design Pattern • The class library Observable represents objects that can be “observed”. – the equivalent of the GUI component in AWT – What would be observed in the MVC architecture? • Objects wishing to be observed can either – subclass Observable, or – have an Observable instance variable • Other objects can implement the Observer interface which correspond to the listeners • An Observer registers itself with the object being observed. • The Observable object invokes notifyObservers() at any time to indicate that it has changed state. • notifyObservers() causes each observer to be sent a message update(Observable, Object), where – first argument is the observable that changed – second argument is optional, but usually provides additional information MVC Design Patterns • MVC also lets you change the way a view responds to user input without changing its visual presentation – A view uses an instance of a Controller subclass to implement a particular response strategy – To implement a different strategy, simply replace the instance with a different kind of controller • e.g., a view can be “disabled” so that it does not accept input simply by giving it a controller that ignores input events – The view-controller relationship is an example of the Strategy design pattern. Strategy Design Pattern • Problem: How do you allow the algorithm that is used to solve a particular problem to be easily and dynamically changed by the client? • Solution: Define a family of algorithms with a similar interface. Each algorithm provides a different strategy for solving the problem at hand. Encapsulate each algorithm, and let the client select the strategy to be used in any situation. Strategy Design Pattern • Example: the creation of layout managers in the AWT – rather that coding in the component library (e.g., frame, panel, etc.) the details of how items are laid out on the screen, these decisions are left to the layout manager. – an interface for LayoutManager is defined – the activities of the GUI components (e.g., frame, panel, etc.) are independent of the layout manager being used. Container inherits Application holds LayoutManager implements GridLayout MVC Design Patterns • MVC – views can be nested • Nested views is supported with the CompositeView class which is a subclass of the View class • CompositeView objects act just like View objects, except they also contain and manage nested views. • This is a specific example of the Composite design pattern using Views. Composite Design Patterns • Problem: How do you permit the creation of complex objects using only simple parts? • Solution: Provide simple components, but allow them to be nested arbitrarily. • Example: Creation of design layouts through the interaction of Components and Containers. – Containers hold a layout manager (border, grid, etc.) – Each item in a layout is a Component. – Composition occurs because Containers are also Components (Containers are a direct subclass of Components). Adapter Design Pattern • Problem: How do you use an object that provides appropriate behavior but uses a different interface than is required in some situation? • Solution: Define an adapter class that acts as an intermediary. The adapter merely translates commands from one form into another • Example: InputStreamRead and OutputStream Writer translate from input/output stream interface into the required reader/writer interface Flyweight Design Pattern • Problem: How can one reduce the storage costs associated with a large number of objects that have a similar state? • Solution: Share state in common with similar objects, thereby reducing the storage required by any single object. • Example: the way Java maintains type information about classes, e.g., type name, description of the interface, etc. – e.g., one Class object for all Strings Abstract Factory Design Pattern • Problem: How to provide a mechanism for creating instances of families of related objects without specifying their concrete representations. • Solution: Provide a method that returns a new value that is characterized only by an interface or parent class, not by the actual type produced. • Example: Collection classes (e.g., Vector) define a method named elements() that is described as returning a value of type Enumeration. – Enumeration is only an interface, not a class – the client is only interested in the behavior common to all values that satisfy the Enumeration interface Factory Design Pattern • Problem: You have a method that returns a newly created object, but you want subclasses to have the ability to return different types of objects. • Solution: Allow the subclass to override the creation method and return a different type of object. • Examples – the clone() method returns a copy of an object – In abstract class ProjectileWorld we used a makeProjectile factory method RevisedCannonWorld extends ProjectileWorld public class RevisedCannonWorld extends ProjectileWorld { public RevisedCannonWorld() { super(); setTitle( "Like the Original CannonWorld" ); } protected { double double double Projectile makeProjectile( int startAngle ) radianAngle = startAngle * Math.PI / 180.0; sinAngle = Math.sin( radianAngle ); cosAngle = Math.cos( radianAngle ); return new CannonBall (20 + (int) (30 * cosAngle), dy(5+(int) (30 * sinAngle)), 5, 12 * cosAngle, -12 * sinAngle ); } } Iterator Design Pattern • Problem: How to provide a way to access elements of an aggregate object sequentially without exposing the underlying representation. • Solution: Provide a mediator object for the sole purpose of sequential access. • Example: The Enumeration interface includes methods for hasMoreElements() and nextElement(). Proxy Design Pattern • Problem: How do you hide details such as transmission protocols to remote objects? • Solution: Provide a proxy that acts as a surrogate or placeholder for another object. • Example: Remote Method Invocation (RMI) system coordinates Java programs running on two or more machines. RMI Proxy Example 1. RMI creates a proxy object that runs on the same machine as the client. 2. The client invokes methods on the proxy. 3. The proxy transmits the method across the network to the server on another computer. 4. The server handles the request, then transmits the results back to the proxy. 5. The proxy hands the result back to the client. Details of the network transmission are hidden from the client. Bridge Design Pattern • Problem: How to decouple an abstraction from its implementation so that the latter can vary independently. • Solution: Remove implementation details from the abstraction, placing them instead in an object that is held as a component in the abstraction. • Example: Most of the component classes in the AWT make use of the bridge pattern. Bridge Example: AWT Window • Actions necessary to implement graphical components vary from platform: Windows, Macs, X-Windows, etc. • Instead of placing platform specific details in the class Window, each window maintains a component of type WindowPeer interface. • The WindowPeer has different implementations depending for each platform. • This separation allows a Java program to be executed on an environment for which a peer is implemented.