Location via proxy:   [ UP ]  
[Report a bug]   [Manage cookies]                
0% found this document useful (0 votes)
28 views

Design Pattern in Java

The document discusses three design patterns: 1. Factory Method - Used to instantiate objects from subclasses based on logic. A factory method accepts arguments and decides which subclass to instantiate based on those arguments. 2. Builder - Used to construct complex objects step-by-step. Different representations can be built using the same construction process. It separates object construction from representation. 3. Prototype - Used when object creation is costly. It allows copying existing objects and modifying them instead of creating them from scratch. It is useful when complex object creation is time consuming.

Uploaded by

Skshail Na
Copyright
© © All Rights Reserved
Available Formats
Download as DOCX, PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
28 views

Design Pattern in Java

The document discusses three design patterns: 1. Factory Method - Used to instantiate objects from subclasses based on logic. A factory method accepts arguments and decides which subclass to instantiate based on those arguments. 2. Builder - Used to construct complex objects step-by-step. Different representations can be built using the same construction process. It separates object construction from representation. 3. Prototype - Used when object creation is costly. It allows copying existing objects and modifying them instead of creating them from scratch. It is useful when complex object creation is time consuming.

Uploaded by

Skshail Na
Copyright
© © All Rights Reserved
Available Formats
Download as DOCX, PDF, TXT or read online on Scribd
You are on page 1/ 17

Advanced

Java
Programming
(J2EE)
Factory Method Design Pattern
A factory method pattern is a creational pattern. It is used to instantiate an object from one
among a set of classes based on a logic.
Assume that you have a set of classes which extends a common super class or interface.
Now you will create a concrete class with a method which accepts one or more arguments.
This method is our factory method. What it does is, based on the arguments passed factory
method does logical operations and decides on which sub class to instantiate. This factory
method will have the super class as its return type. So that, you can program for the
interface and not for the implementation. This is all about factory method design pattern.

Sample factory method design pattern implementation in


Java API
For a reference of how the factory method design pattern is implemented in Java, you can
have a look at SAXParserFactory. It is a factory class which can be used to intantiate SAX
based parsers to pares XML. The method newInstance is the factory method which
instantiates the sax parsers based on some predefined logic.

Block diagram for The Design Pattern

Sample Java Source Code for Factory Method Design


Pattern
Based on comments received from users, I try to keep my sample java source code as simple
as possible for a novice to understand.
Base class:

package com.javapapers.sample.designpattern.factorymethod;

//super class that serves as type to be instantiated for factory method


pattern
public interface Pet {

public String speak();

}
First subclass:
package com.javapapers.sample.designpattern.factorymethod;

//sub class 1 that might get instantiated by a factory method pattern


public class Dog implements Pet {

public String speak() {


return "Bark bark...";
}
}
Second subclass:
package com.javapapers.sample.designpattern.factorymethod;

//sub class 2 that might get instantiated by a factory method pattern


public class Duck implements Pet {
public String speak() {
return "Quack quack...";
}
}
Factory class:
package com.javapapers.sample.designpattern.factorymethod;

//Factory method pattern implementation that instantiates objects based on


logic
public class PetFactory {

public Pet getPet(String petType) {


Pet pet = null;

// based on logic factory instantiates an object


if ("bark".equals(petType))
pet = new Dog();
else if ("quack".equals(petType))
pet = new Duck();
return pet;
}
}
Using the factory method to instantiate
package com.javapapers.sample.designpattern.factorymethod;

//using the factory method pattern


public class SampleFactoryMethod {

public static void main(String args[]){


//creating the factory
PetFactory petFactory = new PetFactory();
//factory instantiates an object
Pet pet = petFactory.getPet("bark");
//you don't know which object factory created
System.out.println(pet.speak());
}

}
Builder Design Pattern
Builder pattern is used to construct a complex object step by step and the final step will
return the object. The process of constructing an object should be generic so that it can be
used to create different representations of the same object.

Complex Object Construction


For example, you can consider construction of a home. Home is the final end product
(object) that is to be returned as the output of the construction process. It will have many
steps, like basement construction, wall construction and so on roof construction. Finally the
whole home object is returned. Here using the same process you can build houses with
different properties.

GOF (Gang Of Four) says,


“Separate the construction of a complex object from its representation so that the same
construction process can create different representations” [GoF 94]

What is the difference between abstract factory and builder pattern?


Abstract factory may also be used to construct a complex object, and then what is the
difference with builder pattern? In builder pattern emphasis is on ‘step by step’. Builder
pattern will have many numbers of small steps. Those every step will have small units of
logic enclosed in it. There will also be a sequence involved. It will start from step 1 and will
go on up to step n and the final step is returning the object. In these steps, every step will
add some value in construction of the object. That is you can imagine that the object grows
stage by stage. Builder will return the object in last step. But in abstract factory how
complex the built object might be, it will not have step by step object construction.
Sample builder design pattern implementation in Java API DocumentBuilderFactory,
StringBuffer, StringBuilder are some examples of builder pattern usage in java API.

Sample Java Source Code for Builder Pattern


Following is the interface that will be returned as the product from the builder.
package com.javapapers.sample.designpattern.builder;

public interface HousePlan {

public void setBasement(String basement);

public void setStructure(String structure);

public void setRoof(String roof);

public void setInterior(String interior);


}

Following is the interface for which the factory implementation should be done. Inturn all
abstract factory will return this type.
package com.javapapers.sample.designpattern.abstractfactory;

public interface AnimalFactory {


public Animal createAnimal();
}
Concrete class for the above interface. The builder constructs an implementation for the
following class.
package com.javapapers.sample.designpattern.builder;

public class House implements HousePlan {

private String basement;


private String structure;
private String roof;
private String interior;

public void setBasement(String basement) {


this.basement = basement;
}

public void setStructure(String structure) {


this.structure = structure;
}

public void setRoof(String roof) {


this.roof = roof;
}

public void setInterior(String interior) {


this.interior = interior;

Builder interface. We will have multiple different implementation of this interface in order
to facilitate, the same construction process to create different representations.
package com.javapapers.sample.designpattern.builder;

public interface HouseBuilder {

public void buildBasement();

public void buildStructure();

public void bulidRoof();

public void buildInterior();

public House getHouse();


}

First implementation of a builder.


package com.javapapers.sample.designpattern.builder;

public class IglooHouseBuilder implements HouseBuilder {

private House house;

public IglooHouseBuilder() {
this.house = new House();
}
public void buildBasement() {
house.setBasement("Ice Bars");
}

public void buildStructure() {


house.setStructure("Ice Blocks");
}

public void buildInterior() {


house.setInterior("Ice Carvings");
}

public void bulidRoof() {


house.setRoof("Ice Dome");
}

public House getHouse() {


return this.house;
}
}

Second implementation of a builder. Tipi is a type of eskimo house.


package com.javapapers.sample.designpattern.builder;

public class TipiHouseBuilder implements HouseBuilder {


private House house;

public TipiHouseBuilder() {
this.house = new House();
}

public void buildBasement() {


house.setBasement("Wooden Poles");
}

public void buildStructure() {


house.setStructure("Wood and Ice");
}

public void buildInterior() {


house.setInterior("Fire Wood");
}

public void bulidRoof() {


house.setRoof("Wood, caribou and seal skins");
}

public House getHouse() {


return this.house;
}

Following class constructs the house and most importantly, this maintains the building
sequence of object.
package com.javapapers.sample.designpattern.builder;

public class CivilEngineer {

private HouseBuilder houseBuilder;

public CivilEngineer(HouseBuilder houseBuilder){


this.houseBuilder = houseBuilder;
}

public House getHouse() {


return this.houseBuilder.getHouse();
}

public void constructHouse() {


this.houseBuilder.buildBasement();
this.houseBuilder.buildStructure();
this.houseBuilder.bulidRoof();
this.houseBuilder.buildInterior();
}
}

Testing the sample builder design pattern.


package com.javapapers.sample.designpattern.builder;

public class BuilderSample {


public static void main(String[] args) {
HouseBuilder iglooBuilder = new IglooHouseBuilder();
CivilEngineer engineer = new CivilEngineer(iglooBuilder);

engineer.constructHouse();

House house = engineer.getHouse();

System.out.println("Builder constructed: "+house);


}
}
Prototype Design Pattern
When creating an object is time consuming and a costly affair and you already have a most
similar object instance in hand, then you go for prototype pattern. Instead of going through
a time consuming process to create a complex object, just copy the existing similar object
and modify it according to your needs.

It’s a simple and straight forward design pattern. Nothing much hidden beneath it. If you
don’t have much experience with enterprise grade huge application, you may not have
experience in creating a complex / time consuming instance. All you might have done is use
the new operator or inject and instantiate.

If you are a beginner you might be wondering, why all the fuss about prototye design
pattern and do we really need this design pattern? Just ignore, all the big guys requires it.
For you, just understand the pattern and sleep over it. You may require it one day in future.

Prototype pattern may look similar to builder design pattern. There is a huge difference to it.
If you remember, “the same construction process can create different representations” is
the key in builder pattern. But not in the case of prototype pattern.

So, how to implement the prototype design pattern? You just have to copy the existing
instance in hand. When you say copy in java, immediately cloning comes into picture. Thats
why when you read about prototype pattern, all the literature invariably refers java cloning.
Simple way is, clone the existing instance in hand and then make the required update to the
cloned instance so that you will get the object you need. Other way is, tweak the cloning
method itself to suit your new object creation need. Therefore whenever you clone that
object you will directly get the new object of desire without modifying the created object
explicitly.

The prototype design pattern mandates that the instance which you are going to copy
should provide the copying feature. It should not be done by an external utility or provider.
But the above, other way comes with a caution. If somebody who is not aware of your
tweaking the clone business logic uses it, he will be in issue. Since what he has in hand is not
the exact clone. You can go for a custom method which calls the clone internally and then
modifies it according to the need. This will be a better approach.

Always remember while using clone to copy, whether you need a shallow copy or deep
copy. Decide based on your business needs. If you need a deep copy, you can use
serialization as a hack to get the deep copy done. Using clone to copy is entirely a design
decision while implementing the prototype design pattern. Clone is not a mandatory choice
for prototype pattern.

In prototype pattern, you should always make sure that you are well knowledgeable about
the data of the object that is to be cloned. Also make sure that instance allows you to make
changes to the data. If not, after cloning you will not be able to make required changes to
get the new required object.

Following sample java source code demonstrates the prototype pattern. I have a basic bike
in hand with four gears. When I want to make a different object, an advance bike with six
gears I copy the existing instance. Then make necessary modifications to the copied
instance. Thus the prototype pattern is implemented. Example source code is just to
demonstrate the design pattern, please don’t read too much out of it. I wanted to make
things as simple as possible.

Sample Java Source Code for Prototype Design Pattern


package com.javapapers.sample.designpattern.prototype;

class Bike implements Cloneable {


private int gears;
private String bikeType;
private String model;
public Bike() {
bikeType = "Standard";
model = "Leopard";
gears = 4;
}

public Bike clone() {


return new Bike();
}

public void makeAdvanced() {


bikeType = "Advanced";
model = "Jaguar";
gears = 6;
}
public String getModel(){
return model;
}
}

public class Workshop {


public Bike makeJaguar(Bike basicBike) {
basicBike.makeAdvanced();
return basicBike;
}
public static void main(String args[]){
Bike bike = new Bike();
Bike basicBike = bike.clone();
Workshop workShop = new Workshop();
Bike advancedBike = workShop.makeJaguar(basicBike);
System.out.println("Prototype Design Pattern: " +
advancedBike.getModel());
}
}
Singleton Design Pattern
Singleton design pattern is the first design pattern I learned (many years back). In early days
when someone asks me, “do you know any design pattern?” I quickly and promptly answer
“I know singleton design pattern” and the question follows, “do you know anything other
than singleton” and I stand stumped!

A java beginner will know about singleton design pattern. At least he will think that he
knows singleton pattern. The definition is even easier than Newton’s third law. Then what is
special about the singleton pattern. Is it so simple and straightforward, does it even deserve
an article? Do you believe that you know 100% about singleton design pattern? If you
believe so and you are a beginner read through the end, there are surprises for you.

There are only two points in the definition of a singleton design pattern,
1. There should be only one instance allowed for a class and
2. We should allow global point of access to that single instance.

GOF says, “Ensure a class has only one instance, and provide a global point of access to it.
[GoF, p127]“.

The key is not the problem and definition. In singleton pattern, trickier part is
implementation and management of that single instance. Two points looks very simple, is it
so difficult to implement it. Yes it is very difficult to ensure “single instance” rule, given the
flexibility of the APIs and many flexible ways available to access an instance. Implementation
is very specific to the language you are using. So the security of the single instance is specific
to the language used.

Strategy for Singleton instance creation


We suppress the constructor and don’t allow even a single instance for the class. But we
declare an attribute for that same class inside and create instance for that and return it.
Factory design pattern can be used to create the singleton instance.

package com.javapapers.sample.designpattern;
public class Singleton {
private static Singleton singleInstance;
private Singleton() {}
public static Singleton getSingleInstance() {
if (singleInstance == null) {
synchronized (Singleton.class) {
if (singleInstance == null) {
singleInstance = new Singleton();
}
}
}
return singleInstance;
}

You need to be careful with multiple threads. If you don’t synchronize the method which is
going to return the instance then, there is a possibility of allowing multiple instances in a
multi-threaded scenario. Do the synchronization at block level considering the performance
issues. In the above example for singleton pattern, you can see that it is thread-safe.
Early and lazy instantiation in singleton pattern
The above example code is a sample for lazy instantiation for singleton design pattern. The
single instance will be created at the time of first call of the getSingleInstance() method. We
can also implement the same singleton design pattern in a simpler way but that would
instantiate the single instance early at the time of loading the class. Following example code
describes how you can instantiate early. It also takes care of the multithreading scenario.

package com.javapapers.sample.designpattern;
public class Singleton {
private static Singleton singleInstance = new Singleton();
private Singleton() {}
public static Singleton getSingleInstance() {
return singleInstance;
}
}

Singleton and Serialization


Using serialization, single instance contract of the singleton pattern can be violated. You can
serialize and de-serialize and get a new instance of the same singleton class. Using java api,
you can implement the below method and override the instance read from the stream. So
that you can always ensure that you have single instance.

ANY-ACCESS-MODIFIER Object readResolve() throws ObjectStreamException;

This article is an attempt to explain the basics on singleton design pattern. If you want more
insight on singleton refer this technical article “When is a Singleton not a Singleton?” and its
references.

Usage of Singleton Pattern in Java API


java.lang.Runtime#getRuntime() java.awt.Desktop#getDesktop()
Adapter Design Pattern

An adapter helps two incompatible interfaces to work together. This is the real world
definition for an adapter. Adapter design pattern is used when you want two different
classes with incompatible interfaces to work together. The name says it all. Interfaces may
be incompatible but the inner functionality should suit the need.

In real world the easy and simple example that comes to mind for an adapter is the travel
power adapter. American socket and plug are different from British. Their interfaces is not
compatible with one another. British plugs are cylindrical and American plugs are
rectangularish. You can use an adapter in between to fit an American (rectangular) plug in
British (cylindrical) socket assuming voltage requirements are met with.

How to implement adapter design pattern?


Adapter design pattern can be implemented in two ways. One using the inheritance method
and second using the composition method. Just the implementation methodology is
different but the purpose and solution is same.

Adapter implementation using inheritance


When a class with incompatible method needs to be used with another class you can use
inheritance to create an adapter class. The adapter class which is inherited will have new
compatible methods. Using those new methods from the adapter the core function of the
base class will be accessed. This is called “is-a” relationship. The same real world example is
implemented using java as below. Dont worry too much about logic, following example
source code attempts to explain adapter design pattern and the goal is simplicity.

public class CylindricalSocket {


public String supply(String cylinStem1, String cylinStem1) {
System.out.println("Power power power...");
}
}

public class RectangularAdapter extends CylindricalSocket {


public String adapt(String rectaStem1, Sting rectaStem2) {
//some conversion logic
String cylinStem1 = rectaStem1;
String cylinStem2 = rectaStem2;
return supply(cylinStem1, cylinStem2);
}
}
public class RectangularPlug {
private String rectaStem1;
private String rectaStem2;
public getPower() {
RectangulrAdapter adapter = new RectangulrAdapter();
String power = adapter.adapt(rectaStem1, rectaStem2);
System.out.println(power);
}
}
Adapter implementation using composition
The above implementation can also be done using composition. Instead of inheriting the
base class create adapter by having the base class as attribute inside the adapter. You can
access all the methods by having it as an attribute. This is nothing but “has-a” relationship.
Following example illustrates this approach. Difference is only in the adapter class and other
two classes are same. In most scenarios, prefer composition over inheritance. Using
composition you can change the behaviour of class easily if needed. It enables the usage of
tools like dependency injection.

public class CylindricalSocket {


public String supply(String cylinStem1, String cylinStem1) {
System.out.println("Power power power...");
}
}

public class RectangularAdapter {


private CylindricalSocket socket;

public String adapt(String rectaStem1, Sting rectaStem2) {


//some conversion logic
socket = new CylindricalSocket();
String cylinStem1 = rectaStem1;
String cylinStem2 = rectaStem2;
return socket.supply(cylinStem1, cylinStem2);
}
}

public class RectangularPlug {


private String rectaStem1;
private String rectaStem2;
public getPower() {
RectangulrAdapter adapter = new RectangulrAdapter();
String power = adapter.adapt(rectaStem1, rectaStem2);
System.out.println(power);
}
}

Adapter design pattern in java API


java.io.InputStreamReader(InputStream)
java.io.OutputStreamWriter(OutputStream)
Proxy Design Pattern
“Provide a surrogate or placeholder for another object to control access to it” is the intent
provided by GoF. Proxy means ‘in place of’. In attendance roll call, we give proxy for our
friends in college right? ‘Representing’ or ‘in place of’ or ‘on behalf of’ are literal meanings
of proxy and that directly explains proxy design pattern. It is one of the simplest and straight
forward design pattern. Proxy design pattern gets second rank in popularity in interviews.
Guess who gets the first rank? None other than singleton design pattern.

Possible Usage Scenarios

 Remote Proxy – Represents an object locally which belongs to a different address


space. Think of an ATM implementation, it will hold proxy objects for bank
information that exists in the remote server. RMI is an example of proxy
implmenetation for this type in java.
 Virtual Proxy – In place of a complex or heavy object use a skeleton representation.
When an underlying image is huge in size, just represent it using a virtual proxy
object and on demand load the real object. You feel that the real object is expensive
in terms of instantiation and so without the real need we are not going to use the
real object. Until the need arises we will use the virtual proxy.
 Protection Proxy – Are you working on a MNC? If so, you might be well aware of the
proxy server that provides you internet. Saying more than provides, the right word is
censores internet. The management feels its better to censor some content and
provide only work related web pages. Proxy server does that job. This is a type of
proxy design pattern. Lighter part of censor is, we search for something critical
in Google and click the result and you get this page is blocked by proxy server. You
never know why this page is blocked and you feel this is genuine. How do you
overcome that, over a period you learn to live with it?
 Smart Reference – Just we keep a link/reference to the real object a kind of pointer.
Proxy Design Pattern Example

Remote Proxy:

Sometime back I wrote an article on a hello-world for Soap Web Service. A part of it
contains implementation of proxy design pattern. The client has the stub files generated
which acts as a proxy for the classes in server side.

Java’s Support for Proxy Design Pattern


From JDK 1.3 java has direct support for implementing proxy design pattern. We need not
worry on mainting the reference and object creation. Java provides us the needed utilities.
Following example implementation explains on how to use java’s api for proxy design
pattern.

package com.javapapers.designpattern.proxy;

public interface Animal {

public void getSound();

}
package com.javapapers.designpattern.proxy;
public class Lion implements Animal {

public void getSound() {


System.out.println("Roar");
}

}
package com.javapapers.designpattern.proxy;

import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;

public class AnimalInvocationHandler implements InvocationHandler {


public AnimalInvocationHandler(Object realSubject) {
this.realSubject = realSubject;
}

public Object invoke(Object proxy, Method m, Object[] args) {


Object result = null;
try {
result = m.invoke(realSubject, args);
} catch (Exception ex) {
ex.printStackTrace();
}
return result;
}

private Object realSubject = null;


}
package com.javapapers.designpattern.proxy;

import java.lang.reflect.Proxy;

public class ProxyExample {

public static void main(String[] args) {


Animal realSubject = new Lion();
Animal proxy = (Animal) Proxy.newProxyInstance(realSubject.getClass()
.getClassLoader(), realSubject.getClass().getInterfaces(),
new AnimalInvocationHandler(realSubject));
proxy.getSound();
}
}
Important Points
 A proxy may hide information about the real object to the client.
 A proxy may perform optimization like on demand loading.
 A proxy may do additional house-keeping job like audit tasks.
 Proxy design pattern is also known as surrogate design pattern.

Proxy Design Pattern Usage in Java API


 java.rmi.* – RMI package is based on proxy design pattern

Adapter vs Proxy Design Pattern


Adapter design pattern provides a different interface from the real object and enables the
client to use it to interact with the real object. But, proxy design pattern provides the same
interface as in the real object.
Decorator vs Proxy Design Patter
Decorator design pattern adds behaviour at runtime to the real object. But, Proxy does not
change the behaviour instead it controls the behaviour.

You might also like