C03043 Ch03 Java Design Patterns
C03043 Ch03 Java Design Patterns
C03043 Ch03 Java Design Patterns
DEVELOPMENT
JAVA Design Patterns
Copyright
The solution describes the elements that make up the design, their
relationships, responsibilities, and collaborations.
:: 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.
11
Java Design Patterns Java Design Patterns
§ 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.
15
The Factory Pattern Java Design Patterns
class Namer { //a 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
}
}
16
The Factory Pattern Java Design Patterns
One classic application of the abstract factory is the case where your system
needs to support multiple “look-and-feel” user interfaces, such as Windows, Motif
or Macintosh:
§ You tell the factory that you want your program to look like Windows and it
returns a GUI factory which returns Windows-like objects.
§ When you request specific objects such as buttons, check boxes and
windows, the GUI factory returns Windows instances of these visual
interface components.
22
The Abstract Factory Pattern Java Design Patterns
:: A Garden Class
A Garden class simply returns one kind of each plant. So, for example, for the
vegetable garden we simply write:
class GardenMaker {
//Abstract Factory which returns one of three gardens
private Garden gd;
public Garden getGarden(String gtype) {
gd = new VegieGarden(); //default
if(gtype.equals("Perennial"))
gd = new PerennialGarden();
if(gtype.equals("Annual"))
gd = new AnnualGarden();
return gd;
}
}
26
The Abstract Factory Pattern Java Design Patterns
The following interaction diagram illustrates how Builder and Director cooperate
with a client.
29
The Builder Pattern Java Design Patterns
:: Pizza Builder
/** "Product" */
class Pizza {
private String dough = "";
private String sauce = "";
private String topping = "";
public void setDough(String dough) {
this.dough = dough; }
public void setSauce(String sauce) {
this.sauce = sauce; }
public void setTopping(String topping) {
this.topping = topping; }
}
32
The Builder Pattern Java Design Patterns
:: Pizza Builder
:: Pizza Builder
/** "ConcreteBuilder" */
class HawaiianPizzaBuilder extends PizzaBuilder {
public void buildDough() {
pizza.setDough("cross"); }
public void buildSauce() {
pizza.setSauce("mild"); }
public void buildTopping() {
pizza.setTopping("ham+pineapple"); }
}
/** "ConcreteBuilder" */
class SpicyPizzaBuilder extends PizzaBuilder {
public void buildDough() {
pizza.setDough("pan baked"); }
public void buildSauce() {
pizza.setSauce("hot"); }
public void buildTopping() {
pizza.setTopping("pepperoni+salami"); }
}
34
The Builder Pattern Java Design Patterns
:: Pizza Builder
/** "Director" */
class Waiter {
private PizzaBuilder pizzaBuilder;
public void setPizzaBuilder(PizzaBuilder pb) {
pizzaBuilder = pb; }
public Pizza getPizza() {
return pizzaBuilder.getPizza(); }
public void constructPizza() {
pizzaBuilder.createNewPizzaProduct();
pizzaBuilder.buildDough();
pizzaBuilder.buildSauce();
pizzaBuilder.buildTopping();
}
}
35
The Builder Pattern Java Design Patterns
:: Pizza Builder
/** A customer ordering a pizza. */
class BuilderExample {
public static void main(String[] args) {
Waiter waiter = new Waiter();
PizzaBuilder hawaiianPizzaBuilder = new HawaiianPizzaBuilder();
PizzaBuilder spicyPizzaBuilder = new SpicyPizzaBuilder();
waiter.setPizzaBuilder( hawaiianPizzaBuilder );
waiter.constructPizza();
Example:
§ Let’s 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.
37
The Prototype Pattern Java Design Patterns
:: Cloning in Java - I
You can make a copy of any Java object using the clone method.
Jobj j1 = (Jobj)j0.clone();
The clone method always returns an object of type Object. You must
cast it to the actual type of the object you are cloning. There are
three other significant restrictions on the clone method:
§ It is a protected method and can only be called from within the
same class or the module that contains that class.
§ You can only clone objects which are declared to implement
the Cloneable interface.
§ Objects that cannot be cloned throw the CloneNotSupported
Exception.
38
The Prototype Pattern Java Design Patterns
:: Cloning in Java - II
This suggests packaging the actual clone method inside the class where it can
access the real clone method:
We create a class called Swimmer that holds one name, club name, sex and time:
class Swimmer {
String name;
int age;
String club;
float time;
boolean female;
public String getName () {return name};
public int getAge () {return age};
public float getTime () {return time};
}
41
The Prototype Pattern Java Design Patterns
§ You can add and remove classes at run time by cloning them as
needed.
§ You can also specify new objects at run time without creating a
proliferation of classes and inheritance structures.
44
The Prototype Pattern Java Design Patterns
The Singleton pattern addresses all the concerns above. With the Singleton design
pattern you can:
§ Ensure that only one instance of a class is created.
§ Provide a global point of access to the object.
§ Allow multiple instances in the future without affecting a singleton class'
clients.
46
The Singleton Pattern Java Design Patterns
protected ClassicSingleton() {
// exists only to defeat instantiation.
}
public static ClassicSingleton getInstance() {
if(instance == null) {
instance = new ClassicSingleton();
}
return instance;
}
}
:: Problems - I
How can a class that does not extend ClassicSingleton create a
ClassicSingleton instance if the ClassicSingleton constructor is
protected?
§ Protected constructors can be called by subclasses and by other
classes in the same package. Hence, because ClassicSingleton and
SingletonInstantiator are in the same package (the default package),
SingletonInstantiator() methods can create ClassicSingleton instances.
Solutions:
1. We can make the ClassicSingleton constructor private so that only
ClassicSingleton’s methods call it; however, that means
ClassicSingleton cannot be subclassed. Also, it's a good idea to
declare the singleton class final, which makes that intention explicit
and allows the compiler to apply performance optimizations.
2. We can put your singleton class in an explicit package, so classes in
other packages (including the default package) cannot instantiate
singleton instances.
50
The Singleton Pattern Java Design Patterns
:: Problems - II
The ClassicSingleton class is not thread-safe.
If two threads – we will call them Thread 1 and Thread 2, call
ClassicSingleton.getInstance() at the same time, two ClassicSingleton
instances can be created if Thread 1 is preempted just after it enters the if
block and control is subsequently given to Thread 2.
Solution: Synchronization
:: Object Adapters
§ 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.
57
The Adapter Pattern Java Design Patterns
:: Example - I
/**
* The SquarePeg class.
* This is the Target class.
*/
public class SquarePeg {
public void insert(String str) {
System.out.println("SquarePeg insert(): " + str);}
}
/**
* The RoundPeg class.
* This is the Adaptee class.
*/
public class RoundPeg {
public void insertIntoHole(String msg) {
System.out.println("RoundPeg insertIntoHole(): " + msg);}
}
:: Example - II
Solution:
/**
* The RoundToSquarePegAdapter class.
* This is the Adapter class.
* It adapts a RoundPeg to a SquarePeg.
* Its interface is that of a SquarePeg.
*/
public class RoundToSquarePegAdapter extends SquarePeg {
private RoundPeg roundPeg;
public RoundToSquarePegAdapter(RoundPeg peg) {
//the roundPeg is plugged into the adapter
this.roundPeg = peg;}
public void insert(String str) {
//the roundPeg can now be inserted in the same manner as a squarePeg!
roundPeg.insertIntoHole(str);}
}
:: Example - III
Example:
// Test program for Pegs.
public class TestPegs {
public static void main(String args[]) {
Execution trace:
SquarePeg insert(): Inserting square peg...
RoundPeg insertIntoHole(): Inserting round peg...
Java Design Patterns 59
60
The Adapter Pattern Java Design Patterns
:: Class Adapters
§ 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.
61
The Adapter Pattern Java Design Patterns
:: Example I
Here are the interfaces for round and square pegs:
/**
*The IRoundPeg interface.
*/
public interface IRoundPeg {
public void insertIntoHole(String msg);
}
/**
*The ISquarePeg interface.
*/
public interface ISquarePeg {
public void insert(String str);
}
:: Example II
Here are the new RoundPeg and SquarePeg classes. These are essentially
the same as before except they now implement the
appropriate interface.
:: Example III
And here is the new PegAdapter class:
/**
* The PegAdapter class.
* This is the two-way adapter class.
*/
public class PegAdapter implements ISquarePeg, IRoundPeg {
private RoundPeg roundPeg;
private SquarePeg squarePeg;
:: Example IV
A client that uses the two-way adapter:
// Test program for Pegs.
public class TestPegs {
public static void main(String args[]) {
:: Example V
Client program output:
An object adapter
§ lets a single Adapter work with many Adaptees - that is, the Adaptee itself
and all of its subclasses (if any). The Adapter can also add functionality to all
Adaptees at once.
§ makes it harder to override Adaptee behavior. It will require subclassing
Adaptee and making Adapter refer to the subclass rather than the Adaptee
itself.
67
The Bridge Pattern Java Design Patterns
Example:
Suppose that we have a program that displays a list of products in a
window. The simplest interface for that display is a simple JList box. But,
once a significant number of products have been sold, we may want to
display the products in a table along with their sales figures.
68
The Bridge Pattern Java Design Patterns
When we design a bridge class, we have to decide how the bridge will determine
which of the several classes it will instantiate. This could be decided based on the
values or quantity of data to be displayed, or based on some simple constants.
Here we define the two constants inside the ListBridge class:
if (table_type == TABLE)
getViewport().add(makeTable(sort)); //make list
}
71
The Bridge Pattern Java Design Patterns
§ You can extend the implementation class and the bridge class
separately, and usually without much interaction with each other.
74
The Composite Pattern Java Design Patterns
:: Example
In the UML class diagram below:
§ The Client uses an abstract component, AComponent, for some abstract task,
operation().
§ At run-time, the Client holds a reference to a concrete component such as
Leaf1 or Leaf2.
§ When the operation task is requested by the Client, the specific concrete
behavior with the particular concrete component will be performed.
76
The Composite Pattern Java Design Patterns
§ 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 cases when certain objects need to be informed about the changes
occured in other objects are frequent. To have a good design means to
decouple as much as possible and to reduce the dependencies. The
Observer Design Pattern can be used whenever a subject has to be
observed by one or more observers.
Intent
Observable - interface or abstract class defining the operations for attaching and
de-attaching observers to the client. In the GOF book this class/interface is known
as Subject.
Observable()
Construct an Observable with zero Observers.
void addObserver(Observer o)
Adds an observer to the set of observers for this object, provided
that it is not the same as some observer already in the set.
protected void clearChanged()
Indicates that this object has no longer changed, or that it has
already notified all of its observers of its most recent change, so that
the hasChanged method will now return false.
int countObservers()
Returns the number of observers of this Observable object.
void deleteObserver(Observer o)
Deletes an observer from the set of observers of this object.
void deleteObservers()
Clears the observer list so that this object no longer has any
observers.
boolean hasChanged()
Tests if this object has changed.
void notifyObservers()
If this object has changed, as indicated by the hasChanged method,
then notify all of its observers and then call the clearChanged method to
indicate that this object has no longer changed.
void notifyObservers(Object arg)
If this object has changed, as indicated by the hasChanged method,
then notify all of its observers and then call the clearChanged method to
indicate that this object has no longer changed.
protected void setChanged()
Marks this Observable object as having been changed; the hasChanged
method will now return true.
82
The Observer Pattern Java Design Patterns
:: Example - I
// A Sub-class of Observable: a Clock Timer
//
import java.util.Observable;
:: Example - II
// A specific Observer to observe ClockTimerModel: DigitalClockView
//
import java.util.Observer;
void draw(){
int hour = obs.GetHour();
int minute = obs.GetMinute();
int second = obs.GetSecond();
// draw operation};
};
:: Example - III
public ObservDemo() {
clockView = new DigitalClockView();
clockModel = new ClockTimerModel();
clockModel.addObserver(clockView);
}
:: Introduction
• 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:
88
The MVC Architectural Pattern
Java Design Patterns
:: Model
:: View
§ 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 model’s 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.
90
The MVC Architectural Pattern
Java Design Patterns
:: Controller
Once a user interacts with the view, the following actions occur:
[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, Addison-
Wesley, 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/mvc-
136693.html