Design Patterns Java
Design Patterns Java
Outline
Patterns Elements Types of Design Patterns The Factory Pattern The Abstract Factory Pattern The Builder Pattern The Prototype Pattern The Singleton Pattern The Adapter Pattern The Bridge Pattern The Composite Pattern Java BluePrints Patterns Catalog
Design Patterns
:: What is a Design Pattern?
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. [1]
[Christopher Alexander]
Design patterns capture the best practices of experienced object-oriented software developers. Design patterns are solutions to general software development problems.
Java Design Patterns 3
Design Patterns
:: Patterns Elements Pattern Name
Design Patterns
:: Patterns Elements The Pattern Name
The pattern name is a handle we can use to describe a design problem, its solutions, and consequences in a word or two.
Naming a pattern immediately increases the design vocabulary. It lets us design at a higher level of abstraction. Having a vocabulary for patterns lets us talk about them. It makes it easier to think about designs and to communicate them and their trade-offs to others.
Design Patterns
:: Patterns Elements The Problem
The problem describes when to apply the pattern.
It explains the problem and its context. It might describe specific design problems such as how to represent algorithms as objects. It might describe class or object structures that are symptomatic of an inflexible design. Sometimes the problem will include a list of conditions that must be met before it makes sense to apply the pattern.
Design Patterns
:: Patterns Elements The Solution
The solution describes the elements that make up the design, their relationships, responsibilities, and collaborations.
The solution doesn't describe a particular concrete design or implementation, because a pattern is like a template that can be applied in many different situations. Instead, the pattern provides an abstract description of a design problem and how a general arrangement of elements (classes and objects in our case) solves it.
Design Patterns
:: Patterns Elements The Consequences
The consequences are the results and trade-offs of applying the pattern.
The consequences for software often concern space and time trade-offs. They may address language and implementation issues as well. Since reuse is often a factor in object-oriented design, the consequences of a pattern include its impact on a system's flexibility, extensibility, or portability. Listing these consequences explicitly helps you understand and evaluate them
Java Design Patterns 8
Design Patterns
:: Types
Erich Gamma, Richard Helm, Ralph Johnson and John Vlisides in their Design Patterns book define 23 design patterns divided into three types: Creational patterns are ones that create objects for you, rather than having you instantiate objects directly. This gives your program more flexibility in deciding which objects need to be created for a given case. Structural patterns help you compose groups of objects into larger structures, such as complex user interfaces or accounting data. Behavioral patterns help you define the communication between objects in your system and how the flow is controlled in a complex program.
Java Design Patterns 9
They have been proven. Patterns reflect the experience, knowledge and insights of developers who have successfully used these patterns in their own work. They are reusable. Patterns provide a ready-made solution that can be adapted to different problems as necessary. They are expressive. Patterns provide a common vocabulary of solutions that can express large solutions succinctly. J2EE provides built in patterns.
10
The creational patterns deal with the best way to create instances of objects. In Java, the simplest way to create an instance of an object is by using the new operator.
This amounts to hard coding, depending on how you create the object within your program. In many cases, the exact nature of the object that is created could vary with the needs of the program and abstracting the creation process into a special creator class can make your program more flexible and general.
Java Design Patterns 11
The Factory Pattern provides a simple decision making class that returns one of several possible subclasses of an abstract base class depending on the data that are provided. The Abstract Factory Pattern provides an interface to create and return one of several families of related objects. The Builder Pattern separates the construction of a complex object from its representation. The Prototype Pattern starts with an initialized and instantiated class and copies or clones it to make new instances rather than creating new instances. The Singleton Pattern is a class of which there can be no more than one instance. It provides a single global point of access to that instance.
Java Design Patterns 12
Here, x is a base class and classes xy and xz are derived from it. The Factory is a class that decides which of these subclasses to return depending on the arguments you give it. The getClass() method passes in some value abc, and returns some instance of the class x. Which one it returns doesn't matter to the programmer since they all have the same methods, but different implementations.
Java Design Patterns 13
Let's consider a simple case where we could use a Factory class. Suppose we have an entry form and we want to allow the user to enter his name either as firstname lastname or as lastname, firstname. Lets make the assumption that we will always be able to decide the name order by whether there is a comma between the last and first name.
class Namer { //a simple class to take a string apart into two names protected String last; //store last name here protected String first; //store first name here public String getFirst() { return first; //return first name } public String getLast() { return last; //return last name } }
Java Design Patterns 14
18
19
20
public class VegieGarden extends Garden { public Plant getShade() { return new Plant("Broccoli"); } public Plant getCenter() { return new Plant("Corn"); } public Plant getBorder() { return new Plant("Peas"); } }
Java Design Patterns 23
24
One of the main purposes of the Abstract Factory is that it isolates the concrete classes that are generated. The actual class names of these classes are hidden in the factory and need not be known at the client level at all. Because of the isolation of classes, you can change or interchange these product class families freely. Since you generate only one kind of concrete class, this system keeps you for inadvertently using classes from different families of products. While all of the classes that the Abstract Factory generates have the same base class, there is nothing to prevent some derived classes from having additional methods that differ from the methods of other classes.
Java Design Patterns 25
Builder - specifies an abstract interface for creating parts of a Product object. ConcreteBuilder - constructs and assembles parts of the product by implementing the Builder interface. Also, it defines and keeps track of the representation it creates and provides an interface for retrieving the product . Director - constructs an object using the Builder interface. Product - represents the complex object under construction.
Java Design Patterns 26
The client creates the Director object and configures it with the desired Builder object. Director notifies the builder whenever a part of the product should be built. Builder handles requests from the director and adds parts to the product. The client retrieves the product from the builder.
The following interaction diagram illustrates how Builder and Director cooperate with a client.
27
The algorithm for creating a complex object should be independent of the parts that make up the object and how they are assembled. The construction process must allow different representations for the object that is constructed.
28
A Builder lets you vary the internal representation of the product it builds. It also hides the details of how the product is assembled. Each specific builder is independent of the others and of the rest of the program. This improves modularity and makes the addition of other builders relatively simple. Because each builder constructs the final product step-by-step, depending on the data, you have more control over each final product that a Builder constructs. A Builder pattern is somewhat like an Abstract Factory pattern in that both return classes made up of a number of methods and objects. The main difference is that while the Abstract Factory returns a family of related classes, the Builder constructs a complex object step by step depending on the data presented to it.
29
The Prototype pattern specifies the kinds of objects to create using a prototypical instance, and create new objects by copying this prototype. A Protoype pattern is used when creating an instance of a class is very timeconsuming or complex in some way. Then, rather than creating more instances, you make copies of the original instance and modify them as appropriate. Prototypes can also be used whenever you need classes that differ only in the type of processing they offer, for example in parsing of strings representing numbers in different radixes. In this sense, the prototype is nearly the same as the Examplar pattern described by Coplien [4].
Example: Lets consider the case of an extensive database where you need to make a number of queries to construct an answer. Once you have this answer as a table or ResultSet, you might like to manipulate it to produce other answers without issuing additional queries.
Java Design Patterns 30
public class SwimData implements Cloneable { public Object clone() { try{ return super.clone(); } catch(Exception e) { System.out.println(e.getMessage()); return null; } } }
Java Design Patterns 32
implementation has the advantage of encapsulating the try-catch block inside the public clone method. Note that if you declare this public method to have the same name clone, it must be of type Object, since the internal protected method has that signature. We could, however, change the name and do the typecasting within the method instead of forcing it onto the user: public SwimData cloneMe() { try{ return (SwimData)super.clone(); } catch(Exception e) { System.out.println(e.getMessage()); return null; } } Java Design Patterns
33
In the original class, the records are sorted by name, while in the cloned class, they are sorted by time.
for(int i=0; i< sxdata.size(); i++) //display sorted values from clone { Swimmer sw = sxdata.getSwimmer(i); System.out.println(sw.getName()+" "+sw.getTime()); }
Java Design Patterns 36
You can add and remove classes at run time by cloning them as needed. You can revise the internal data representation of a class at run time based on program conditions. You can also specify new objects at run time without creating a proliferation of classes and inheritance structures.
37
The Singleton pattern ensures a class has only one instance, and provides a global point of access to it. The class itself is responsible for keeping track of its sole instance. The class can ensure that no other instance can be created (by intercepting requests to create new objects), and it can provide a way to access the instance. Singletons maintain a static reference to the sole singleton instance and return a reference to that instance from a static instance() method.
40
The ClassicSingleton class employs a technique known as lazy instantiation to create the singleton; as a result, the singleton instance is not created until the getInstance() method is called for the first time. This technique ensures that singleton instances are created only when needed. The ClassicSingleton class implements a protected constructor so clients cannot instantiate ClassicSingleton instances; however, the following code is perfectly legal:
44
It can be difficult to subclass a Singleton, since this can only work if the base Singleton class has not yet been instantiated. We can easily change a Singleton to allow a small number of instances where this is allowable and meaningful. We can use the same approach to control the number of instances that the application uses. Only the operation that grants access to the Singleton instance needs to change. The Singleton pattern permits refinement of operations and representation. The Singleton class may be subclassed, and it is easy to configure an application with an instance of this extended class. You can configure the application with an instance of the class you need at run-time.
45
Structural patterns describe how classes and objects can be combined to form larger structures. The difference between class patterns and object patterns is that class patterns describe how inheritance can be used to provide more useful program interfaces. Object patterns, on the other hand, describe how objects can be composed into larger structures using object composition, or the inclusion of objects within other objects. The Structural patterns are: Adapter Composite Proxy Flyweight Faade Bridge Decorator
Java Design Patterns 46
The Adapter pattern can be used to make one class interface match another to make programming easier. The Composite pattern is a composition of objects, each of which may be either simple or itself a composite object.
The Proxy pattern is frequently a simple object that takes the place of a more complex object that may be invoked later, for example when the program runs in a network environment.
47
The Flyweight pattern is a pattern for sharing objects, where each instance does not contain its own state, but stores it externally. This allows efficient sharing of objects to save space, when there are many instances, but only a few different types. The Faade pattern is used to make a single class represent an entire subsystem. The Bridge pattern separates an objects interface from its implementation, so you can vary them separately. The Decorator pattern, which can be used to add responsibilities to objects dynamically.
Java Design Patterns 48
Adapters are used to enable objects with different interfaces to communicate with each other. The Adapter pattern is used to convert the programming interface of one class into that of another. We use adapters whenever we want unrelated classes to work together in a single program. Adapters come in two flavors, object adapters and class adapters. The concept of an adapter is thus pretty simple; we write a class that has the desired interface and then make it communicate with the class that has a different interface. Adapters in Java can be implemented in two ways: by inheritance, and by object composition.
49
Object adapters use a compositional technique to adapt one interface to another. The adapter inherits the target interface that the client expects to see, while it holds an instance of the adaptee. When the client calls the request() method on its target object (the adapter), the request is translated into the corresponding specific request on the adaptee. Object adapters enable the client and the adaptee to be completely decoupled from each other. Only the adapter knows about both of them.
50
If a client only understands the SquarePeg interface for inserting pegs using the insert() method, how can it insert round pegs, which are pegs, but that are inserted differently, using the insertIntoHole() method?
51
// // // // //
Now we'd like to do an insert using the round peg. But this client only understands the insert() method of pegs, not a insertIntoHole() method. The solution: create an adapter that adapts a square peg to a round peg!
Execution trace:
SquarePeg insert(): Inserting square peg... RoundPeg insertIntoHole(): Inserting round peg...
53
Class adapters use multiple inheritance to achieve their goals. As in the object adapter, the class adapter inherits the interface of the client's target. However, it also inherits the interface of the adaptee as well. Since Java does not support true multiple inheritance, this means that one of the interfaces must be inherited from a Java Interface type. Both of the target or adaptee interfaces could be Java Interfaces. The request to the target is simply rerouted to the specific request that was inherited from the adaptee interface.
54
55
56
public void insert(String str) { roundPeg.insertIntoHole(str);} public void insertIntoHole(String msg){ squarePeg.insert(msg);}
}
Java Design Patterns 57
58
59
62
63
64
65
The Bridge pattern is intended to keep the interface to your client program constant while allowing you to change the actual kind of class you display or use. This can prevent you from recompiling a complicated set of user interface modules, and only require that you recompile the bridge itself and the actual end display class. You can extend the implementation class and the bridge class separately, and usually without much interaction with each other.
67
69
The Composite pattern allows you to define a class hierarchy of simple objects and more complex composite objects so that they appear to be the same to the client program. Because of this simplicity, the client can be that much simpler, since nodes and leaves are handled in the same way. The Composite pattern also makes it easy for you to add new kinds of components to your collection, as long as they support a similar programming interface. The composite is essentially a singly-linked tree, in which any of the objects may themselves be additional composites.
Java Design Patterns 70
72
The client class instantiates the ConcreteObservable object. Then it instantiate and attaches the concrete observers to it using the methods defined in the Observable interface. Each time the state of the subject it's changing it notifies all the attached Observers using the methods defined in the Observer interface. When a new Observer is added to the application, all we need to do is to instantiate it in the client class and to add attach it to the Observable object. The classes already created will remain unchanged.
73
74
75
class ClockTimerModel extends Observable { public: ClockTimer(); int GetHour(){return hour}; int GetMinute(){return minute}; int GetSecond(){return second}; void tick(){ // update internal time-keeping state // ... // The Observable object notifies all its registered observers setChanged(); notifyObservers();}; private: int hour; int minute; int second; };
In green are the changes to be applied to the class to be made an observable class.
Java Design Patterns 76
77
78
79
Business Delegate - Reduce coupling between Web and Enterprise JavaBeansTM tiers Composite Entity - Model a network of related business entities Composite View - Separately manage layout and content of multiple composed views Data Access Object (DAO) - Abstract and encapsulate data access mechanisms Fast Lane Reader - Improve read performance of tabular data Front Controller - Centralize application request processing Intercepting Filter - Pre- and post-process application requests Model-View-Controller - Decouple data representation, application behavior, and presentation Service Locator - Simplify client access to enterprise business services Session Facade - Coordinate operations between multiple business objects in a workflow Transfer Object - Transfer business data between tiers Value List Handler - Efficiently iterate a virtual list View Helper - Simplify access to model state and data access logic
80
MVC was first introduced by Trygve Reenskaug at the Xerox Palo Alto Research Center in 1979. Part of the basic of the Smalltalk programming environment. Widely used for many object-oriented designs involving user interaction. A three-tier architectural model:
81
manages the behavior and data of the application domain, responds to requests for information about its state (usually from the view), responds to instructions to change state (usually from the controller). In event-driven systems, the model notifies observers (usually views) when the information changes so that they can react. (see observer pattern) In enterprise software, a model often serves as a software approximation of a real-world process. In a game, the model is represented by the classes defining the game entities, which are embedding their own state and actions.
82
Renders the model into a form suitable for interaction, typically a user interface element. Multiple views can exist for a single model for different purposes. The view renders the contents of a portion of the models data. If the model data changes, the view must update its presentation as needed. This can be achieved by using: a push model, in which the view registers itself with the model for change notifications (see the observer pattern) a pull model, in which the view is responsible for calling the model when it needs to retrieve the most current data.
83
Receives user input and initiates a response by making calls on appropriate model objects. Accepts input from the user and instructs the model to perform actions based on that input. The controller translates the user's interactions with the view it is associated with, into actions that the model will perform. A controller may also spawn new views upon user demand.
84
2.
3.
85
2. 3.
4.
86
Resources
[1] Christopher Alexander, Sara Ishikawa, Murray Silverstein, Max Jacobson, Ingrid Fiksdahl-King, and Shlomo Angel. A Pattern Language. Oxford University Press, New York, 1977. [2] Erich Gamma, Richard Helm, Ralph Johnson and John Vlissides, Design Patterns Elements of Reusable Object-Oriented Software, Adisson-Wesley, 1995. [3] James W. Cooper, The Design Patterns Java Companion Elements of Reusable Object-Oriented Software, Adisson-Wesley, 1998. [4] James O. Coplien, Advanced C++ Programming Styles and Idioms, AddisonWesley, Reading, MA., 1992. [5] David Geary, Simply Singleton, Java Design Patterns at JavaWorld, April 2003, http://www.javaworld.com/columns/jw-java-design-patterns-index.shtml [6] Design Patterns, http://www.exciton.cs.rice.edu/JavaResources/DesignPatterns/ [7] Robert Eckstein, Java SE Application Design With MVC, Oracle Technology Network, March 2007. http://www.oracle.com/technetwork/articles/javase/mvc136693.html
87