Thursday, May 13, 2010

Object Oriented Design Patterns



These are just convenient ways of reusing object-oriented code between projects and between programmers.
In software engineering, a design pattern is a general repeatable solution to a commonly occurring problem in software design.
The process of looking for these patterns is called “pattern mining,”

Creational Patterns
All of the creational patterns deal with the best way to create instances of objects.

The Factory Method 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 i.e., Creates an instance of several derived classes .
Factory method is just a fancy name for a method that instantiates objects. Like a factory, the job of the factory method is to create -- or manufacture -- objects.

public class DBConnectionFactory
{
String type;
public DBConnectionFactory (String type) {
type = t;
}
public Conection createConnection(String type) {
if(type.equals("Oracle")) {
return new OracleConnection();
} else if("MS-SQL") {
return new MSSQLConnection();
} else {
return new MySQLConnection();
}
}
}

public class TestDBConnectionFactory {
public static void main(String args[]){
DBConnectionFactory dbfac = new DBConnectionFactory("Oracle");
Connection con = dbfac.createConnection();
}
}
------------------------------------------------------------------------

The Abstract Factory Method provides an interface to create and return one of several families of related objects.

public abstract DBConnectionFactory {
public DBConnectionFactory {
}
protected abstract Connection createConnection(String type);
}

public class SecureConnectionFactory extends DBConnectionFactory {
public Conection createConnection(String type) {
if(type.equals("Oracle")) {
return new SecureOracleConnection();
} else if("MS-SQL") {
return new SecureMSSQLConnection();
} else {
return new SecureMySQLConnection();
}
}
}

public class SecureOracleConnection extends Connection {
public SecureOracleConnection () {
Class.forName("Oracle driver class");
con = DriverManager.createConnection(.....);
}
}

public class SecureMSSQLConnection extends Connection {
public SecureMSSQLConnection () {....}
}

public class SecureMySQLConnection extends Connection {
public SecureMySQLConnection () {....}
}

public class TestDBConnectionFactory {
public static void main(String args[]){
SecureConnectionFactory scfac = new SecureConnectionFactory ();
Connection con = scfac.createConnection("Oracle");
}
}
------------------------------------------------------------------------

The Builder Pattern separates the construction of a complex object from its representation, so that several different representations can be created depending on the needs of the program.
Parse a complex representation, create one of several targets.
The "director" invokes "builder" services as it interprets the external format. The "builder" creates part of the complex object each time it is called and maintains all intermediate state. When the product is finished, the client retrieves the result from the "builder".

public interface RobotBuildable {
public void go();
}

import java.util.*;
public class CookieRobotBuildable extends RobotBuildable {
ArrayList actions;
public CookieRobotBuildable() {
}
public void loadActions(ArrayList a) {
actions = a;
}
public void go() {
Iterator itr = actions.iterator();
while (itr.hasNext()) {
switch ((Integer) itr.next())
case 1:
start();
break;
case 2:
getparts();
break;
case 3:
assemble();
break;
case 4:
test();
break;
case 5:
stop();
break;
}
}
public void start() {System.out.println("Starting...");}
public void getParts() {System.out.println("Getting flour and sugar...");}
public void assemble() {System.out.println("Baking a cookie...");}
public void test() {System.out.println("Crunching a cookie...");}
public void stop() {System.out.println("Stoping...");}
}


------------------------------------------------------------------------

The Prototype Pattern starts with an initialized and instantiated class and copies or clones it to make new instances rather than creating new instances.

  • Specify the kinds of objects to create using a prototypical instance, and create new objects by copying this prototype.
  • Co-opt one instance of a class for use as a breeder of all future instances.
  • The new operator considered harmful.
Prototypical Object --->Object Cloner --->Object Customizer --->Customized Object
Prototypes are useful when object initialization is expensive, and you anticipate few variations on the initialization parameters. In this context, Prototype can avoid expensive "creation from scratch", and support cheap cloning of a pre-initialized prototype.
------------------------------------------------------------------------

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.

//Singleton with final field
public class Elvis {
public static final Elvis INSTANCE = new Elvis();
private Elvis() {... }
...
//Singleton with static factory
public class Elvis {
private static final Elvis INSTANCE = new Elvis();
private Elvis() { ... }
public static Elvis getInstance() {
return INSTANCE;
}
...
------------------------------------------------------------------------

Object Pool Object pooling can offer a significant performance boost; it is most effective in situations where the cost of initializing a class instance is high, the rate of instantiation of a class is high, and the number of instantiations in use at any one time is low.
Object pools (otherwise known as resource pools) are used to manage the object caching. A client with access to a Object pool can avoid creating a new Objects by simply asking the pool for one that has already been instantiated instead. Generally the pool will be a growing pool, i.e. the pool itself will create new objects if the pool is empty, or we can have a pool, which restricts the number of objects created.
It is desirable to keep all Reusable objects that are not currently in use in the same object pool so that they can be managed by one coherent policy. To achieve this, the Reusable Pool class is designed to be a singleton class.
------------------------------------------------------------------------

Structural patterns
In Software Engineering, Structural Design Patterns are Design Patterns that ease the design by identifying a simple way to realize relationships between entities.


The Adapter pattern, used to change the interface of one class to that of another one.
Convert the interface of a class into another interface clients expect. Adapter lets classes work together that couldn't otherwise because of incompatible interfaces.
Wrap an existing class with a new interface.
Impedance match an old component to a new system
Adapter makes things work after they're designed; Bridge makes them work before they are.
Adapter is meant to change the interface of an existing object.
often referred to as the wrapper pattern or simply a wrapper
An adapter allows classes to work together that normally could not because of incompatible interfaces by wrapping its own interface around that of an already existing class.

/* the client class should instantiate adapter objects */
/* by using a reference of this type */
interface Stack {
void push (T o);
T pop ();
T top ();
}

/* DoubleLinkedList is the adaptee class */
class DList {
public void insert (DNode pos, T o) { ... }

public void remove (DNode pos) { ... }

public void insertHead (T o) { ... }

public void insertTail (T o) { ... }
public T removeHead () { ... }
public T removeTail () { ... }

public T getHead () { ... }

public T getTail () { ... }

}

/* Adapt DList class to Stack interface is the adapter class */
class DListImpStack extends DList implements Stack {
public void push (T o) {

insertTail (o);
}
public T pop () {

return removeTail ();

}
public T top () {

return getTail ();

}

}

------------------------------------------------------------------------

The Bridge pattern, intended to keep the interface to your client program constant while allowing you to change the actual kind of class you display or use. You can then change the interface and the underlying class separately.
There are two parts of your code that are co-mingled and two different parts are changing rapidly. The idea behind bridge design pattern is to separate these parts apart and connect them with a well designed bridge connection, so that these two parts are no more comingled and can be handled separately. The idea is to keep both parts separately so that they can be handled more effectively.

Remote and car have has-relationship i.e., each remote type has a car object.
So we have a Toyota Alarm remote, Honda Alarm remote, Toyota Remote Starter ...and so on.
------------------------------------------------------------------------

The Composite pattern, a collection of objects, any one of which may be either itself a Composite, or just a primitive object.
  • Compose objects into tree structures to represent whole-part hierarchies. Composite lets clients treat individual objects and compositions of objects uniformly.
  • Recursive composition
  • "Directories contain entries, each of which could be a directory."
  • 1-to-many "has a" up the "is a" hierarchy

Each leaf node should be treated same as a branch node i.e., files and directories should be treated similiarly
// ***** Define a "lowest common denominator" *****
interface AbstractFile {
public void ls();

}


// ***** File implements the "lowest common denominator"
class File implements AbstractFile {
private String m_name;

public File(String name) {

m_name = name;

}

public void ls() {
System.out.println(CompositeDemo.g_indent + m_name);

}

}


// ***** Directory implements the "lowest common denominator"
class Directory implements AbstractFile {
private String m_name;

private ArrayList m_files = new ArrayList();

public Directory(String name) {

m_name = name;

}

public void add(Object obj) {
m_files.add(obj);

}

public void ls() {

System.out.println(CompositeDemo.g_indent + m_name);

CompositeDemo.g_indent.append(" ");
for (int i = 0; i <>
// ***** Leverage the "lowest common denominator"

AbstractFile obj = (AbstractFile)m_files.get(i);
obj.ls();
}

CompositeDemo.g_indent.setLength(CompositeDemo.g_indent.length() - 3);

}
}
------------------------------------------------------------------------

The Decorator pattern, a class that surrounds a given class, adds new capabilities to it, and passes all the unchanged methods to the underlying class.
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.
Adds functionality to existing methods by supplying wrapper classes and without modifying code of existing classes.

public class Computer {
public Computer () {}
public String description () { return "a computer";}
}
public class Disk extends Computer {
Computer com;
public Disk() {}
public Disk (Computer com) {this.com = com;}
public String description () { return com.description() + " a disk";}
}
public class Monitor extends Disk {
Disk disk;
public Monitor() {}
public Monitor (Computer com) {this.disk = (Disk) com;}
public String description () { return disk.description() + " a monitor";}
}
public class TestComputer {
public static void main (String args[]) {
Computer com = new Computer();
com = new Disk(com);
com = new Monitor(com);
com = new Monitor(com);
System.out.println("You r getting " + com.description());
}
}
Output You r getting a computer a disk a monitor a monitor

------------------------------------------------------------------------

The Façade pattern, which groups a complex object hierarchy and provides a new, simpler interface to access those data.
Provide a unified interface to a set of interfaces in a subsystem. Facade defines a higher-level interface that makes the subsystem easier to use.
Wrap a complicated subsystem with a simpler interface.
A segment of the client community needs a simplified interface to the overall functionality of a complex subsystem.
The Adapter pattern changes the interface of one or more classes into one interface that a client is expecting.
Facade may provide a simplified interface to a single class with a very complex interface.
Facade defines a new interface, whereas Adapter uses an old interface.
The Facade defines a unified, higher level interface to a subsystem that makes it easier to use. Consumers encounter a Facade when ordering from a catalog. The consumer calls one number and speaks with a customer service representative. The customer service representative acts as a Facade, providing an interface to the order fulfillment department, the billing department, and the shipping department.

------------------------------------------------------------------------

The Flyweight pattern, which provides a way to limit the proliferation of small, similar class instances by moving some of the class data outside the class and passing it in during various execution methods.
Use sharing to support large numbers of fine-grained objects efficiently.
In Java String pooling implements Flyweight pattern.


If your code generates a large number of heavy objects then you can have one or small number of flyweight objects created on the fly using different configurations and it appears that these are actual heavy objects and you can avoid instantiating each of heavy objects.
Instead of having multiple Student Object just have a single student object configured each time on the fly

public class Student {
String name;
int id, score;
double averageScore;
public Student(double a) {averageScore = a;}
public double getAverageScore() {return averageScore;}
public void setAverageScore(double averageScore) {this.averageScore = averageScore;}
public int getId() {return id;}
public void setId(int id) {this.id = id;}
public String getName() {return name;}
public void setName(String name) {this.name = name;}
public int getScore() { return score;}
public void setScore(int score) {this.score = score;}
public double studentStanding() { //gives percentile of student
return (((double)score) / averageScore - 1.0) *100.0;
}
}
public class TestFlyweight {
public static void main(String[] args) {
String names[] = {"Ralph","Alice","Sam"};
int ids[] = {1001, 1002, 1003};
int scores[] = {45, 55, 65};
double total = 0;
for(int i=0; i
------------------------------------------------------------------------

The Proxy pattern, which provides a simple place-holder class for a more complex class which is expensive to instantiate.
It lets you work with remote objects and makes it appear to be localobject for the client.
RMI uses proxy pattern for generating proxy client object i.e., stub.
Provide a surrogate or placeholder for another object to control access to it.
Use an extra level of indirection to support distributed, controlled, or intelligent access.
Add a wrapper and delegation to protect the real component from undue complexity.
Adapter provides a different interface to its subject. Proxy provides the same interface.
Decorator provides an enhanced interface. Decorator and Proxy have different purposes but similar structures.
------------------------------------------------------------------------

Behavioral Patterns
Behavioral patterns are those patterns that are most specifically concerned with communication between objects.

The Observer pattern defines the way a number of classes can be notified of a change
Define a one-to-many dependency between objects so that when one object changes state, all its dependents are notified and updated automatically.
The "View" part of Model-View-Controller.
Observer objects register themselves in the Subject Object and all observers get notified when an event occurs inside the Subject.
Obsever can also unregister inorder to not get notifications anymore.

import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.*;
public class TestButton extends JPanel {
public TestButton (JButton button, final JTextField text) {
super();
add(button);
add(text);
//Button is subject, ActionListener is observer
//ActionListener is registered with Button
//When button is clicked ActionListener is notified to take action

button.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
text.setText("Button Clicked");
}
});
}
public static void main(String[] args){
JFrame frame = new JFrame("ButtonDemo");
JButton button = new JButton("Test");
JTextField text = new JTextField(30);
frame.getContentPane().add("Center",new TestButton(button, text));
frame.pack();
frame.show();
}
}
------------------------------------------------------------------------
The Mediator defines how communication between classes can be simplified by using another class to keep all classes from having to know about each other.
  • Define an object that encapsulates how a set of objects interact. Mediator promotes loose coupling by keeping objects from referring to each other explicitly, and it lets you vary their interaction independently.
  • Design an intermediary to decouple many peers.
  • Promote the many-to-many relationships between interacting peers to "full object status".
Helps to mediate (acts as connecting link) between parts of the program.
Example Shopping-Store web-site has following pages and navigations between them that needs to be hardcoded in each page
Now intoduce the mediator object interface that handles all the logic for navigation from one page to another, and web-pages need not have to know about navigation logic involved but they just have to work with mediator (loosely coupling the code i.e., code separation)
Extract quickly changing code and put it one location where it is handled easily.

------------------------------------------------------------------------

The Chain of Responsibility allows an even further decoupling between classes, by passing a request between classes until it is recognized.
  • 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.
  • Launch-and-leave requests with a single processing pipeline that contains many possible handlers.
  • An object-oriented linked list with recursive traversal.
ATM use the Chain of Responsibility in money giving mechanism.
------------------------------------------------------------------------

The Template pattern provides an abstract definition of an algorithm,
Define the skeleton of an algorithm in an operation, deferring some steps to client subclasses. Template Method lets subclasses redefine certain steps of an algorithm without changing the algorithm's structure.
Base class declares algorithm 'placeholders', and derived classes implement the placeholders.
Template Method uses inheritance to vary part of an algorithm.
Factory Method is a specialization of Template Method
Same code of Builder Pattern we have a robot builder template is used and now we can build various types of robots
Check code of BuilderPattern reused

import java.util.*;
public class AutomotiveRobot extends RobotBuildable {
ArrayList actions;
public AutomotiveRobot() {
}
public void loadActions(ArrayList a) {
actions = a;
}
public void go() {
Iterator itr = actions.iterator();
while (itr.hasNext()) {
switch ((Integer) itr.next())
case 1:
start();
break;
case 2:
getparts();
break;
case 3:
assemble();
break;
case 4:
test();
break;
case 5:
stop();
break;
}
}
public void start() {System.out.println("Starting...");}
public void getParts() {System.out.println("Getting Carborator...");}
public void assemble() {System.out.println("Assemble carborator...");}
public void test() {System.out.println("Starting carborator...");}
public void stop() {System.out.println("Stoping...");}
}
public class TestTemplate {
public static void main(String args[]) {
AutomotiveRobot automotiveRobot
= new AutomotiveRobot ("Automotive Robot);
CookieRobot cookieRobot = new CookieRbot(Cookie Robot);
System.out.println(automotiveRobot.getName() + ":" );
automotiveRobot.go();
System.out.println(cookieRobot.getName() + ":" );
cookieRobot.go();
}
}

Actions are same in both robots as they extends same interface but what they do is different i.e., customized differently.
------------------------------------------------------------------------

The Strategy pattern encapsulates an algorithm inside a class,
Define a family of algorithms, encapsulate each one, and make them interchangeable. Strategy lets the algorithm vary independently from the clients that use it.
Capture the abstraction in an interface, bury implementation details in derived classes.
Modes of transportation to an airport is an example of a Strategy. Several options exist such as driving one's own car, taking a taxi, an airport shuttle, a city bus, or a limousine service. For some airports, subways and helicopters are also available as a mode of transportation to the airport. Any of these modes of transportation will get a traveler to the airport, and they can be used interchangeably. The traveler must chose the Strategy based on tradeoffs between cost, convenience, and time.
The problem that strategy design pattern addresses is that you need not override your base class code functionality over separate generations of inheritance. Thus the purpose of inheritance is violated. With strategy design pattern you dont have to alter your code (override your base class functionality) into various generations of inheritance.

public abstract class Vehicle {
private GoAlgorithm goAlgorithm;
public Vehicle () {}
public void setGoAlgorithm(GoAlgorithm goAlgorithm) {
this.goAlgorithm = goAlgorithm;
}
public void go(){
goAlgorithm.go();
}
}
public interface GoAlgorithm {
public void go();
}
public class GoDrivingAlgorithm implements GoAlgorithm {
public void go() {
System.out.println("I m driving");
}
}
public class GoFlyingAlgorithm implements GoAlgorithm {

public void go() {
System.out.println("I m flying");
}
}
public class GoFlyingFastAlgorithm implements GoAlgorithm {

public void go() {
System.out.println("I m flying fast");
}
}
public class RaceCar extends Vehicle{
public RaceCar() {
setGoAlgorithm(new GoDrivingAlgorithm());
}
}
public class FormulaOneCar extends Vehicle{
public FormulaOneCar() {
setGoAlgorithm(new GoDrivingAlgorithm());
}
}
public class Helicopter extends Vehicle{
public Helicopter() {
setGoAlgorithm(new GoFlyingAlgorithm());
}
}
public class Jet extends Vehicle{
public Jet() {
setGoAlgorithm(new GoFlyingFastAlgorithm());
}
}
public class TestVehicle {
public static void main(String[] args) {
RaceCar raceCar = new RaceCar();
raceCar.go();
FormulaOneCar foc = new FormulaOneCar();
foc.go();
Helicopter helicopter = new Helicopter();
helicopter.go();
Jet jet = new Jet();
jet.go();
}
}


OUTPUT I m driving
I m driving
I m flying
I m flying fast

------------------------------------------------------------------------

The Visitor pattern adds function to a class
The purpose of the Visitor design pattern is to allow new operations to be added to a class hierarchy without recompiling the class hierarchy.
Represent an operation to be performed on the elements of an object structure. Visitor lets you define a new operation without changing the classes of the elements on which it operates.
The classic technique for recovering lost type information.
Do the right thing based on the type of two objects.
Double dispatch
The Visitor pattern represents an operation to be performed on the elements of an object structure without changing the classes on which it operates. This pattern can be observed in the operation of a taxi company. When a person calls a taxi company (accepting a visitor), the company dispatches a cab to the customer. Upon entering the taxi the customer, or Visitor, is no longer in control of his or her own transportation, the taxi (driver) is.

A Visitor is like a plumber who is called to a house to fix something. The house is “visitable”, i.e. it allows Visitors to enter. However, it doesn’t know how to fix the plumbing, so it calls a plumber. The plumber, however, doesn’t know anything about the house. It only knows about plumbing. The house knows about itself, so when the Visitor comes in the house, the house doesn’t even know whether the Visitor is a plumber or electrician or painter. But it does know that it has rooms.
So, when a Visitor enters the house (programatically through the house’s accept(Visitor visitor) method), it allows the Visitor to look at it first. It then shows (i.e. passes) the Visitor to each room in the house (through each room’s own accept(Visitor visitor) method). When the Visitor enters a room (as it did when it entered the house itself), it knows if that room has plumbing or not. If no plumbing is in the room, the Visitor does nothing; if there is plumbing, then the Visitor does what it is programmed to do.
Interestingly, the way the Visitor checks each room to see if it is interested in it is to have the room pass itself into the Visitor’s visit() method (i.e. visitor.visit(this)). The Visitor thus has access to the internals of that room/object. This is how it determines if it has any work to do with that particular object.
This process of the Visitor being passed in through the Visitable object’s accept() method and then the Visitable object being passed into the Visitor through its visit() method is called “double dispatch”.
------------------------------------------------------------------------

The State pattern provides a memory for a class’s instance variables.
Objects can alter its behaviour depending on its internal state. Object given same inputs but based on different internal state of the object output is different.
Four states of a program that rents out apartments, waiting for someone to get an application and so on.
The Class has a variable state which can have following valid states and based on the value of this state variable the class behaves differently.
------------------------------------------------------------------------

The Command pattern provides a simple way to separate execution of a command from the interface environment that produced it
  • Encapsulate a request as an object, thereby letting you parameterize clients with different requests, queue or log requests, and support undoable operations.
  • Promote "invocation of a method on an object" to full object status
  • An object-oriented callback
The Command pattern allows requests to be encapsulated as objects, thereby allowing clients to be parameterized with different requests.
Encapsulate commands (list of commnads) as a single object, object corresponds to each actions.
Creating command object which are easily used tool set of commands.
The code that receives (is the target for the command) is receiver and client code that invokes command on target is invoker.
Crisis server needs to manage all three servers remotely, and run desired commands (remotely) separately on the desired server can be cumbersome.
So encapsulate set of command into command object. Have object for each action you want to perform on these servers. Encapsulated command object can have n commands in it but is a easily used tool set.
------------------------------------------------------------------------

The Iterator pattern formalizes the way we move through a list of data within a class.
  • Provide a way to access the elements of an aggregate object sequentially without exposing its underlying representation.
  • The C++ and Java standard library abstraction that makes it possible to decouple collection classes and algorithms.
  • Promote to "full object status" the traversal of a collection.
  • Polymorphic traversal

Iterators loops through collection of object, have following methods: next(), hasNext(), remove()
------------------------------------------------------------------------

The memento pattern is a software design pattern that provides the ability to restore an object to its previous state (undo via rollback).
  • Without violating encapsulation, capture and externalize an object's internal state so that the object can be returned to this state later.
  • A magic cookie that encapsulates a "check point" capability.
  • Promote undo or rollback to full object status.
The Memento design pattern defines three distinct roles:
Originator - the object that knows how to save itself.
Caretaker - the object that knows why and when the Originator needs to save and restore itself.
Memento - the lock box that is written and read by the Originator, and shepherded by the Caretaker.
Save the state of object (database) as a backup
A client code should not have access to backup object, as it can modify it, so this backup object should be private to the database object.

------------------------------------------------------------------------
The intent of a Null Object is to encapsulate the absence of an object by providing a substitutable alternative that offers suitable default do nothing behavior. In short, a design where "nothing will come of nothing"
------------------------------------------------------------------------