Search This Blog

Wednesday, January 20, 2010

Java Design Pattern

JAVA DESIGN PATTERNS
Creational Patterns
All the creational patterns define the best possible way in which an object can be instantiated. These describes the best way to CREATE object instances. Now everyone knows the object instance in Java can be created using a new operator.

Book book = new Book ();
So, what’s the great stuff? Well, that’s true. The new Operator creates the instance of an object, but this is hard-coding. As I have said earlier, creating good software is difficult and so, hard coding is the last thing one should do. Also, at times the very nature of the object which is created can change according to the nature of the program. In such scenarios, we can make use of patterns to give this a more general and flexible approach.

There are five types of Creational Patterns.
1. Factory Pattern
2. Abstract Factory Pattern
3. Builder Pattern
4. Prototype Pattern
5. Singleton Pattern
Structural Patterns
Structural Patterns describe how objects and classes can be combined to form larger structures. The difference between class patterns and object patterns is that class patterns describe abstraction with the help of inheritance and how it can be used to provide more useful program interface. Object patterns, on other hand, describe how objects can be associated and composed to form larger, more complex structures.
There are seven structural patterns described. They are as follows:
Patterns.
1. Adapter Pattern
2. Bridge Pattern
3. Composite Pattern
4. Decorator Pattern
5. Facade Pattern
6. Flyweight Pattern
7. Proxy Pattern
Behavioral Patterns
Behavioral patterns are those which are concerned with interactions between the objects. The interactions between the objects should be such that they are talking to each other and still are loosely coupled. The loose coupling is the key to n-tier architectures. In this, the implementation and the client should be loosely coupled in order to avoid hard-coding and dependencies.
The behavioral patterns are:
Patterns.
1. Chain of Resposibility Pattern
2. Command Pattern
3. Interpreter Pattern
4. Iterator Pattern
5. Mediator Pattern
6. Momento Pattern
7. Observer Pattern
8. State Pattern
9. Strategy Pattern
10. Template Pattern
11. Visitor Pattern


Creational Patterns - Factory Pattern
Factory of what? Of classes. In simple words, if we have a super class and n sub-classes, and based on data provided, we have to return the object of one of the sub-classes, we use a factory pattern.

Let’s take an example to understand this pattern.
Example: Let’s suppose an application asks for entering the name and sex of a person. If the sex is Male (M), it displays welcome message saying Hello Mr. and if the sex is Female (F), it displays message saying Hello Ms .

The skeleton of the code can be given here.
public class Person {
// name string
public String name;
// gender : M or F
private String gender;
public String getName() {
return name;
}

public String getGender() {
return gender;
}
}// End of class
This is a simple class Person having methods for name and gender. Now, we will have two sub-classes, Male and Female which will print the welcome message on the screen.
public class Male extends Person {
public Male(String fullName) {
System.out.println("Hello Mr. "+fullName);
}
}// End of class

Also, the class Female
public class Female extends Person {
public Female(String fullNname) {
System.out.println("Hello Ms. "+fullNname);
}
}// End of class
Now, we have to create a client, or a SalutationFactory which will return the welcome message depending on the data provided.
public class SalutationFactory {
public static void main(String args[]) {
SalutationFactory factory = new SalutationFactory();
factory.getPerson(args[0], args[1]);
}
public Person getPerson(String name, String gender) {
if (gender.equals("M"))
return new Male(name);
else if(gender.equals("F"))
return new Female(name);
else
return null;
}
}// End of class
This class accepts two arguments from the system at runtime and prints the names.
Running the program:
After compiling and running the code on my computer with the arguments Prashant and M:
java Prashant M
The result returned is: “Hello Mr. Prashant”.
When to use a Factory Pattern?
The Factory patterns can be used in following cases:
1. When a class does not know which class of objects it must create.
2. A class specifies its sub-classes to specify which objects to create.
3. In programmer’s language (very raw form), you can use factory pattern where you have to create an object of any one of sub-classes depending on the data provided
Creational Patterns - Abstract Factory Pattern
This pattern is one level of abstraction higher than factory pattern. This means that the abstract factory returns the factory of classes. Like Factory pattern returned one of the several sub-classes, this returns such factory which later will return one of the sub-classes.

Let’s understand this pattern with the help of an example.
Suppose we need to get the specification of various parts of a computer based on which work the computer will be used for.

The different parts of computer are, say Monitor, RAM and Processor. The different types of computers are PC, Workstation and Server.

So, here we have an abstract base class Computer.
package creational.abstractfactory;
public abstract class Computer {
/**
* Abstract method, returns the Parts ideal for
* Server
* @return Parts
*/
public abstract Parts getRAM();
/**
* Abstract method, returns the Parts ideal for
* Workstation
* @return Parts
*/
public abstract Parts getProcessor();
/**
* Abstract method, returns the Parts ideal for
* PC
* @return Parts
*/
public abstract Parts getMonitor();
}// End of class
This class, as you can see, has three methods all returning different parts of computer. They all return a method called Parts. The specification of Parts will be different for different types of computers. Let’s have a look at the class Parts.
package creational.abstractfactory;
public class Parts {
/**
* specification of Part of Computer, String
*/
public String specification;
/**
* Constructor sets the name of OS
* @param specification of Part of Computer
*/
public Parts(String specification) {
this.specification = specification;
}
/**
* Returns the name of the part of Computer
*
* @return specification of Part of Computer, String
*/
public String getSpecification() {
return specification;
}
}// End of class

And now lets go to the sub-classes of Computer. They are PC, Workstation and Server.
package creational.abstractfactory;
public class PC extends Computer {
/**
* Method over-ridden from Computer, returns the Parts ideal for
* Server
* @return Parts
*/
public Parts getRAM() {
return new Parts("512 MB");
}
/**
* Method over-ridden from Computer, returns the Parts ideal for
* Workstation
* @return Parts
*/
public Parts getProcessor() {
return new Parts("Celeron");
}
/**
* Method over-ridden from Computer, returns the Parts ideal for
* PC
* @return Parts
*/
public Parts getMonitor() {
return new Parts("15 inches");
}
}// End of class

package creational.abstractfactory;

public class Workstation extends Computer {
/**
* Method over-ridden from Computer, returns the Parts ideal for
* Server
* @return Parts
*/
public Parts getRAM() {
return new Parts("1 GB");
}
/**
* Method over-ridden from Computer, returns the Parts ideal for
* Workstation
* @return Parts
*/
public Parts getProcessor() {
return new Parts("Intel P 3");
}
/**
* Method over-ridden from Computer, returns the Parts ideal for
* PC
* @return Parts
*/
public Parts getMonitor() {
return new Parts("19 inches");
}
}// End of class

package creational.abstractfactory;
public class Server extends Computer{
/**
* Method over-ridden from Computer, returns the Parts ideal for
* Server
* @return Parts
*/
public Parts getRAM() {
return new Parts("4 GB");
}
/**
* Method over-ridden from Computer, returns the Parts ideal for
* Workstation
* @return Parts
*/
public Parts getProcessor() {
return new Parts("Intel P 4");
}
/**
* Method over-ridden from Computer, returns the Parts ideal for
* PC
* @return Parts
*/
public Parts getMonitor() {
return new Parts("17 inches");
}
}// End of class
Now let’s have a look at the Abstract factory which returns a factory “Computer”. We call the class ComputerType.
package creational.abstractfactory;
/**
* This is the computer abstract factory which returns one
* of the three types of computers.
*
*/
public class ComputerType {
private Computer comp;
public static void main(String[] args) {
ComputerType type = new ComputerType();
Computer computer = type.getComputer("Server");
System.out.println("Monitor: "+computer.getMonitor().getSpecification());
System.out.println("RAM: "+computer.getRAM().getSpecification());
System.out.println("Processor: "+computer.getProcessor().getSpecification());
}
/**
* Returns a computer for a type
*
* @param computerType String, PC / Workstation / Server
* @return Computer
*/
public Computer getComputer(String computerType) {
if (computerType.equals("PC"))
comp = new PC();
else if(computerType.equals("Workstation"))
comp = new Workstation();
else if(computerType.equals("Server"))
comp = new Server();
return comp;
}
}// End of class
Running this class gives the output as this:
Monitor: 17 inches
RAM: 4 GB
Processor: Intel P 4.
When to use Abstract Factory Pattern?
One of the main advantages of Abstract Factory Pattern is that it isolates the concrete classes that are generated. The names of actual implementing classes are not needed to be known at the client side. Because of the isolation, you can change the implementation from one factory to another.

Creational Patterns - Singleton Pattern
This is one of the most commonly used patterns. There are some instances in the application where we have to use just one instance of a particular class. Let’s take up an example to understand this.
A very simple example is say Logger, suppose we need to implement the logger and log it to some file according to date time. In this case, we cannot have more than one instances of Logger in the application otherwise the file in which we need to log will be created with every instance.
We use Singleton pattern for this and instantiate the logger when the first request hits or when the server is started.
package creational.singleton;
import org.apache.log4j.Priority;
import java.text.SimpleDateFormat;
import java.util.GregorianCalendar;
import java.util.Properties;
import java.io.InputStream;
import java.io.FileOutputStream;
import java.io.PrintStream;
import java.io.IOException;
public class Logger {
private String fileName;
private Properties properties;
private Priority priority;
/**
* Private constructor
*/
private Logger() {
logger = this;
}
/**
* Level of logging, error or information etc
*
* @return level, int
*/
public int getRegisteredLevel() {
int i = 0;
try {
InputStream inputstream = getClass().getResourceAsStream("Logger.properties");
properties.load(inputstream);
inputstream.close();
i = Integer.parseInt(properties.getProperty("**logger.registeredlevel**"));
if(i < 0 || i > 3)
i = 0;
}
catch(Exception exception) {
System.out.println("Logger: Failed in the getRegisteredLevel method");
exception.printStackTrace();
}
return i;
}
/**
* One file will be made daily. So, putting date time in file
* name.
*
* @param gc GregorianCalendar
* @return String, name of file
*/
private String getFileName(GregorianCalendar gc) {
SimpleDateFormat dateFormat1 = new SimpleDateFormat("dd-MMM-yyyy");
String dateString = dateFormat1.format(gc.getTime());
String fileName = "C:\\prashant\\patterns\\log\\PatternsExceptionLog-" + dateString + ".txt";
return fileName;
}
/**
* A mechanism to log message to the file.
*
* @param p Priority
* @param message String
*/
public void logMsg(Priority p, String message) {
try {
GregorianCalendar gc = new GregorianCalendar();
String fileName = getFileName(gc);
FileOutputStream fos = new FileOutputStream(fileName, true);
PrintStream ps = new PrintStream(fos);
SimpleDateFormat dateFormat2 = new SimpleDateFormat("EEE, MMM d, yyyy 'at' hh:mm:ss a");
ps.println("<"+dateFormat2.format(gc.getTime())+">["+message+"]");
ps.close();
}
catch (IOException ie) {
ie.printStackTrace();
}
}
/**
* this method initialises the logger, creates an object
*/
public static void initialize() {
logger = new Logger();
}
// singleton - pattern
private static Logger logger;
public static Logger getLogger() {
return logger;
}
}// End of class
Difference between static class and static method approaches:
One question which a lot of people have been asking me. What’s the difference between a singleton class and a static class? The answer is static class is one approach to make a class “Singleton”.
We can create a class and declare it as “final” with all the methods “static”. In this case, you can’t create any instance of class and can call the static methods directly.
Example:
final class Logger {
//a static class implementation of Singleton pattern
static public void logMessage(String s) {
System.out.println(s);
}
}// End of class
//==============================
public class StaticLogger {
public static void main(String args[]) {
Logger.logMessage("This is SINGLETON");
}
}// End of class
The advantage of this static approach is that it’s easier to use. The disadvantage of course is that if in future you do not want the class to be static anymore, you will have to do a lot of recoding.
Structural Patterns - Facade Pattern
Facade as the name suggests means the face of the building. The people walking past the road can only see this glass face of the building. They do not know anything about it, the wiring, the pipes and other complexities. The face hides all the complexities of the building and displays a friendly face.
This is how facade pattern is used. It hides the complexities of the system and provides an interface to the client from where the client can access the system. In Java, the interface JDBC can be called a facade. We as users or clients create connection using the “java.sql.Connection” interface, the implementation of which we are not concerned about. The implementation is left to the vendor of driver.
Let’s try and understand the facade pattern better using a simple example. Let’s consider a store. This store has a store keeper. In the storage, there are a lot of things stored e.g. packing material, raw material and finished goods.

You, as client want access to different goods. You do not know where the different materials are stored. You just have access to store keeper who knows his store well. Whatever you want, you tell the store keeper and he takes it out of store and hands it over to you on showing him the credentials. Here, the store keeper acts as the facade, as he hides the complexities of the system Store.

Let us see how the Store example works.

Store.java
package structural.facade;
public interface Store {
public Goods getGoods();
}// End of interface
The store can very well be an interface. This only returns Goods. The goods are of three types as discussed earlier in this document. RawMaterialGoods, FinishedGoods and PackagingMaterialsGoods. All these classes can implement the Goods interface.
Similarly, the stores are of three types and can implement the Store interface. Let’s have a look at the code for one of the stores.

FinishedGoodsStore.java
package structural.facade;
public class FinishedGoodsStore implements Store {
public Goods getGoods() {
FinishedGoods finishedGoods = new FinishedGoods();
return finishedGoods;
}
}// End of class
Now let’s consider the facade StoreKeeper.
StoreKeeper.java
package structural.facade;
public class StoreKeeper {
/**
* The raw materials are asked for and
* are returned
*
* @return raw materials
*/
public RawMaterialGoods getRawMaterialGoods() {
RawMaterialStore store = new RawMaterialStore();
RawMaterialGoods rawMaterialGoods = (RawMaterialGoods)store.getGoods();
return rawMaterialGoods;
}

/**
* The packaging materials are asked for and
* are returned
*
* @return packaging materials
*/
public PackingMaterialGoods getPackingMaterialGoods() {
PackingMaterialStore store = new PackingMaterialStore();
PackingMaterialGoods packingMaterialGoods = (PackingMaterialGoods)store.getGoods();
return packingMaterialGoods;
}

/**
* The finished goods are asked for and
* are returned
*
* @return finished goods
*/
public FinishedGoods getFinishedGoods() {
FinishedGoodsStore store = new FinishedGoodsStore();
FinishedGoods finishedGoods = (FinishedGoods)store.getGoods();
return finishedGoods;
}
}// End of class
This is clear that the complex implementation will be done by StoreKeeper himself. The client will just access the StoreKeeper and ask for either finished goods, packaging material or raw material.
How will the client program access this façade? Here is a simple code.

Client.java
package structural.facade;
public class Client {
/**
* to get raw materials
*/
public static void main(String[] args) {
StoreKeeper keeper = new StoreKeeper();
RawMaterialGoods rawMaterialGoods = keeper.getRawMaterialGoods();
}
}// End of class
In this way the implementation is left to the façade. The client is given just one interface and can access only that. This hides all the complexities.
There is another way of implementing this. We can have just one method in our StoreKeeper class getGoods(String goodsType).
Another version of StoreKeeper method is here.

StoreKeeper.java
package structural.facade;
public class StoreKeeper {
/**
* The common method
*
* @return Goods
*/
public Goods getGoods(String goodsType) {
if (goodsType.equals("Packaging")) {
PackingMaterialStore store = new PackingMaterialStore();
PackingMaterialGoods packingMaterialGoods = (PackingMaterialGoods)store.getGoods();
return packingMaterialGoods;
}
else if (goodsType.equals("Finished")) {
FinishedGoodsStore store = new FinishedGoodsStore();
FinishedGoods finishedGoods = (FinishedGoods)store.getGoods();
return finishedGoods;
}
else {
RawMaterialStore store = new RawMaterialStore();
RawMaterialGoods rawMaterialGoods = (RawMaterialGoods)store.getGoods();
return rawMaterialGoods;
}
}// End of class
The client program can now create an object of StoreKeeper class and call method getGoods() passing as parameter the type of goods required. This can be done as follows.
new StoreKeeper().getGoods(“RawMaterials”);
In this case, the type-casting ill be needed on client side to narrow down Goods to RawMaterialsGoods.
All in all, the Façade pattern hides the complexities of system from the client and provides a simpler interface. Looking from other side, the facade also provides the implementation to be changed without affecting the client code
Structural Patterns - Proxy Pattern
The proxy pattern is used when you need to represent a complex with a simpler one. If creation of object is expensive, its creation can be postponed till the very need arises and till then, a simple object can represent it. This simple object is called the “Proxy” for the complex object

The cases can be innumerable why we can use the proxy. Let’s take a scenario. Say, we want to attach an image with the email. Now, suppose this email has to be sent to 1 lakh consumers in a campaign. Attaching the image and sending along with the email will be a very heavy operation. What we can do instead is, send the image as a link to one of the sevlet. The place holder of the image will be sent. Once the email reaches the consumer, the image place holder will call the servlet and load the image at run time straight from the server.

Let’s try and understand this pattern with the help of a non-software example as we have tried to do throughout this article.

Let’ say we need to withdraw money to make some purchase. The way we will do it is, go to an ATM and get the money, or purchase straight with a cheque. In old days when ATMs and cheques were not available, what used to be the way??? Well, get your passbook, go to bank, get withdrawal form there, stand in a queue and withdraw money. Then go to the shop where you want to make the purchase. In this way, we can say that ATM or cheque in modern times act as proxies to the Bank.

Let’s look at the code now.

Bank will define the entire method described above. There are references of classes like You (as the person who wants to withdraw money), also Account, as persons account. These are dummy classes and can be considered of fulfilling the responsibilities as described.


Bank.java
package structural.proxy;
/**
* Bank.java
* The class acts as the main object for which
* the proxy has to be created. As described, going
* to bank for withdrawal is very costly time wise.
*/
public class Bank {
private int numberInQueue;
/**
* Method getMoneyForPurchase
* This method is responsible for the entire banking
* operation described in the write-up
*/
public double getMoneyForPurchase(double amountNeeded) {

// get object for person
You you = new You("Prashant");
// get obj for account
Account account = new Account();
// get person's account number
String accountNumber = you.getAccountNumber();
// passbook got.
boolean gotPassbook = you.getPassbook();
// get number in queue
int number = getNumberInQueue();

// the number will decrease every few mins
while (number != 0) {
number--;
}

// now when the number = 0, check if balance is sufficient
boolean isBalanceSufficient = account.checkBalance(accountNumber, amountNeeded);
if(isBalanceSufficient)
return amountNeeded;
else
return 0;
}

/**
* returns the number in the queue
*/
private int getNumberInQueue() {
return numberInQueue;
}
}// End of class
Also, the second class is ATMProxy. This also defines the way the transaction can be handled for withdrawal of money.

ATMProxy.java
package structural.proxy;

public class ATMProxy {
/**
* Method getMoneyForPurchase
* This method is responsible for the entire banking
* operation described in the write-up
*/
public double getMoneyForPurchase(double amountNeeded) {

// get obj of You to get card
You you = new You("Prashant");
// get obj for account
Account account = new Account();

boolean isBalanceAvailable = false;
// if card there, go ahead
if(you.getCard()) {
isBalanceAvailable = account.checkBalance(you.getAccountNumber(), amountNeeded);
}

if(isBalanceAvailable)
return amountNeeded;
else
return 0;
}
}// End of class
Here, we can also create another proxy called ChequeProxy. I am not creating it here as the message I wanted to send across has been conveyed with the help of one proxy only. We can see here that creation of object of Bank is very costly, effort and time wise, and so, we can as well use a proxy called ATM to get the result. ATM can internally communicate with the Bank object. So, ATM here is also acting like a façade.
This might and might not happen. It can happen that we at a later stage have to create the same heavy object. We just want to postpone the creation of object to the last minute so that the application is not loaded by resources utilized for creating the object

No comments:

Post a Comment

Note: Only a member of this blog may post a comment.