Location via proxy:   [ UP ]  
[Report a bug]   [Manage cookies]                

Design Patterns

Download as docx, pdf, or txt
Download as docx, pdf, or txt
You are on page 1of 12

Creational Design Patterns

As the name suggests these design patterns are used to control the instantiation of a class. Why do we
need it? Because the program should not be dependent on how an user of the class instantiates it. The
supplier of the class should take the responsibility of controlling the instantiation process in case it
affects the execution of the program. For Example: if a class is supposed to have only one instance for
it to work properly for an application then in such a case the supplier of the class needs to make the
necessary arrangements that all the users of that cass get only the one shared instance. This is
normally achieved by using the Singleton Design Pattern which we'll discuss next.

Few popular Creational Design Patterns

The Singleton Pattern - this design pattern is used to ensure that only one instance of the class is
being used across the entire application. For example: you may like to use this design pattern to
implement Cache of an application. How do we implement the singleton Design Pattern? The easiest
way is to have a static variable storing the refence of the shared instance and keeping the
constructor(s) private so that the users can't call the new operator to create instances. Such an
implementation provides a static public method to the consumers to get the shared instance.

class SingletonImpl{
...
private static singletonInstance = null;
...
private SingletonImpl(){
...
}
public synchronized static getSingleton(){
if(singletonInstance == null) singletonInstance = new SingletonImpl();
return singletonInstance;}
...
}

The Factory Pattern - this design pattern is used to return an instance of one of several possible
classes depending on what parameters are actually passed by the consumer. How do we implement this
design pattern? We normally use inheritance to implement this. Suppose we have a base class named
'Base' and two chilldren of this base class named 'Child1' and 'Child2'. Now the Factory class which is the
decision making body based on what the consumer provides decides whether to return an instance of
the class 'Child1' or 'Child2'. We can easily set the return type of the method of the Factory (which is
exposed to the consumers) as the Base Class type and then the method can easily return instances of
either of the two children.

class BaseClass {
...
}
class Child1 extends BaseClass{
...
}
class Child2 extends BaseClass{
...
}
public class FactoryImpl{
...
public BaseClass getChild(String parameter){
...
if(parameter.equals("Child1")) //... sample cond impl
return new Child1();
else return new Child2();
}
...
}

The Abstract Factory Pattern - this design pattern is very similar to the Factory Pattern with the only
difference that it takes the abstraction to another level higher. This pattern is basically used to return
one of several related classes of objects i.e., one of several Factories (which in turn return the actual
instance based on the passed parameter as explained above). One common example of this design
pattern is to implement user interfaces. Suppose you're building an UI for three platforms - Windows,
Mac, and Linux. Now you can use Abstract Factory pattern to return each of the Factories (Windows,
Mac, and Linux) which will themselves return one of the various UI Components based on the passed
parameter.

public abstract class UI{


public abstract UIComponent getButton(int, int, int, int);
...
}
public class UIComponent{
private int x1;private int y1;private int x2;private int y2;
public UIComponent(int x1, int y1, int x2, int y2){...}
}
public class Button extends UIComponent{...}
...
public class WindowsUI extends UI{...}
public class UIFactory {
private UI ui;
public UI getUI(String type){
if(type.equals("Win")) ui = new WindowsUI();
...
return ui;
}
}

This is just a sample implementation to help you understand how actually we make use of the Abstract
Factory Pattern. The actual UI implmenetation will of course be quite different.

Structural Design Patterns

Design Patterns belonging to this category are used to combine classes and objects to form larger
structures to suit your requirements. How do we actually achieve this? Class based structural design
patterns use Inheritance to form larger structures whereas Object based structural design patterns use
Composition for the same. The most popular structural design patterns are The Adapter Design Pattern,
The Decorator Design Pattern, The Bridge Design Pattern, The Composite Design Pattern, The Proxy
Design Pattern, The Facade Design Pattern, and The Flyweight Design Pattern.

We'll see Adapter, Decorator, and Composite Design Patterns in this article and discuss the other
structural design patterns in subsequent articles. In this article we'll also see how the three design
patterns (which look to be very similar) - Adapter, Decorator, and Composite differ from each other.

Adapter Design Pattern

As the name might suggest this design pattern is used where an unrelated class having a different
interface is required to accept calls to the methods which are actually part of some other class having
a different interface. How to do it? Well... there are the same two ways which we discussed above -
using Interfaces and Composition. Suppose we have two classes A and B where we would like to have an
instance of the type A to accept calls to the methods of class B then using inheritance we can derive a
sub-class (say C) from A and add those methods of Class B into the new sub-class C so that they can be
called on an instance of class C which will of course be of type A. Using composition we can simply
have a new class which will have the original non-compliant class as a member and we'll add the
required methods in this new class to internally call the corresponding methods of the non-compliant
member class.
Example: Adapter Using Inheritance

class A{

public void methodA(int a){


...
}

...

class B{

public void methodB(){


...
}

...

class C extends class A{

public void methodB(){

...

int intValue = 5; //compute the actual int value

methodA(intValue);

...
}

Example: Adapter Using Composition

class A{

public void methodA(int a){


...
}

...

class B{

public void methodB(){


...
}

...

class C{

private A objectRefA;
...

public void methodB(){

int intValue = 5; //compute the actual int value

objectRefA.methodA(intValue);

}
...

Decorator Design Pattern

This design pattern is used to decorate the behavior of individual objects of a class without having to
create a new derived class. It's normally used in UI design. Suppose there is a requirement where some
of the instances of an UI component need a differnt look and feel (maybe based on the section of the
screen they appear at or due to any other possible reason) then in such a case creating those many
position-based derived classes of that UI component doesn't seem to be a good idea. Instead we can
have a Decorator class having the basic look and feel and from it we can derive classed which will
render those specific position-based look and feel. This will make the UI design more flexible by
separating the actual UI component with its position-dependent look-n-feel. The same UI component
can be used for all its occurrences with the corresponding decorator classes. Here the decorator classes
will contain the actual UI component as a member and apply the area/position based look-n-feel logic
on the contained instance(s).

class UIComp1{
...
}

class Decorator{

//...basic decoration of components


...

class DecoratorUIComp1Header extends Decorator{

//...Header specific decoration for UIComp1


...

Composite Design Pattern


This design pattern is used to make a composite of several primitive or composite member objects to
have a common class which can accept calls intended to a variety of specialized objects (or cases). The
composite children are normally termed as nodes and the primitives are called leaves. Example:
suppose we need a common method which returns the specialized technical skills of an employee and
all of its reportees (if the employee has any) then the Employee class may have a data structure (say a
Vector) to store all the reportees which will themselves be instances of the Employee class only. Now
we can have a common method getExpertise which will club the skills of the Employee which those of
the reportees (if any) and return the clubbed data.

class Employee{

...
private String skill;
private Vector reportees;
...

public String getExpertise(){

String expertise = skill;

for(int i = 0; i < reportees.length; ++i)


expertise += ((Employee)reportees.elementAt(i)).getExpertise();

return expertise;
}

...

How do Adapters, Decorators and Composites differ?

Adapters may seem to decorate, but they are primarily used for enabling a class to accept calls
belonging to a different interface. We have already sen above how inheritance and composition can be
used to achieve this.

Decorators are not used to add different methods to all the instances instead they are used to add
specific behavior to some specific instances. Though Adapters making use of composition may also be
used here, but the intention is different here with what it's in case of a Adapter.
As discussed above, Composites are mainly used to provide a single interface to multiple instances
which internally may have different structures depending on the values of the composed members in
each of these instances. In the example discussed above we see that every Employee instance will
invoke the same method 'getExpertise()' irespective of whether the instance represents a Employee
having no reportees or the one who is having reportees (each of these reportees may themselves have
their own reportees).

Structural Patterns contd. - Bridge, Facade, Flyweight, Proxy

If you have directly reached to this article then you may like to first go through thefirst article on
structural design patterns which covers what they are all about and discusses Adapter, Decorator, and
Composite design patterns in particular.

Bridge Design Pattern

This design pattern is used to achieve the very basic purpose of Object Oriented Programming, which is
to separate the interface of a class from its implementation. This approach has the obvious advantage
of achieving the flexibility of being able to alter the implementation any time one wants to without
affecting the client code using the class. Sounds similar to the Adapter Design Pattern? Well... it's
actually similar to that, but the intent is quite different. The Adapter Design Pattern is used to enable
the interfaces of one or more classes to look like and be compatible to the interface of a particular
class whereas in case Bridge Design Pattern the class is designed in such a way that the interface is
fixed and separate from the implementation. Here we don't have one or more classes to make
compatible with the interface of some other class instead we separate the interface of a class from its
implementation so that we can have the liberty of distributing the interface to be used by clients
without being tightly tied to a particular implementation. Any future changes in the implementation
won't affect the client code and this requirement can be really crucial in some cases. For example: if
the class is being used to display some data then in future the revised implementation may be used
provide additionaldetails/graphs. This will only require to replace the older implementation with the
newer one.

How can we implement this design pattern? Very simple... by just having an interface and subsequently
implementing the interface in one or more classes. We of course need to have a fixed interface
otherwise the very purpose of this design pattern to provide the flexibility of having a loosely coupled
implementation won't be achieved.

Facade Design Pattern

This design pattern is primarily used to achieve simplicity. The pattern provides a simpler interface
with no or little details of the underlying subsystems so that the normal users can simply use them in
their client code easily. The advanced users can of course go to the subsystem level to achieve access
to more detailed information.

Another obvious advantage of Facade Design Pattern is that it makes the normal client code
independent of the particular implementations of the subsystems as the normal client uses the higher
level interface having no details of subsystems. This facilitates any combination of the subsystems to
work well for such a client without requiring any client code changes.

How to implement this design pattern? Just think of the higher level interface and extend that
interface for different subsystems. Now you are free to have any implementation for the subsystems
without being worried about the clients which used the higher level interface.

Flyweight Design Pattern

This design pattern is used in the cases where we have multiple instances with only little lighter (in
terms of storage required) differences. In such a case we can have save externally that part (which is
typically heavier) of the object state which is similar across the instances and make it shared so that
all the instances can point to that. This will help us having only that data in an instance which is prone
to change from one instance to another. Such an approach may allow the instances to offload the
heavier part of their payload to one shared place in the memory and in turn we'll end up saving
the space and the time to create that heavy part redundantly for every instance. Such an approach can
be really helpful in the cases where the number of instances are quite high.

How to implement this design pattern? You can create a separate singleton class for the non-changing
heavier part and in the actual class you can have a reference to that singleton instance. Not sure how
to implement a singleton class? You may like to go through this article - Singleton Implementation in
Java >>

Proxy Design Pattern

This design pattern is used to have a simpler object (often called the Proxy object) in place of the
more complex object which actually serves the client requests. The simpler object passes the calls to
the actual object, maybe after doing somemanipulation or transformation. The simpler object makes
the life of the client developer easy and s/he doesn't bother about the transformation and other low-
level details which the Proxy object handles for them.

The stub and skeleton in RMI do a similar stuff. The client and the server only need to send the raw
details to them and they take care of marshalling and unmarshalling.

How to implement this design pattern? Have a simpler higher level class (you can again use the Bridge
pattern to design this class) and the method definitions of this class should actually do the required
transformation and once the actual parametersare ready then they should call the corresponding
methods of the lower level more detailed class which actually does the required stuff.

Liked the article? You may like to Subscribe to this blog for regular updates. You may also like to
follow the blog to manage the bookmark easily and to tell the world that you enjoy GeekExplains. You
can find the 'Followers' widget in the rightmost sidebar.

Builder Design Pattern - this design pattern is used for building a different set of objects based on
some passed parameters. We already know that Factory Pattern also does a similar thing, so why to
have a different design pattern. Well... Factory Pattern is used to return objects of different type
(descendents of a common base class) based on passed parameters, but here we build a set of objects
and not just return a descendant object. Got the point?

Let's take an example to understand it better. Suppose you have some data (let's say a table) which you
would like to be shown using different graph types based on how many records the table has. For
instance, if the number of records are less than 5 then you would like to have a pie-chart otherwise a
bar-chart. In such a case this design pattern suggests you to have an abstract class representing the
base data (the records to be shown in our case, say in form of Vector or some other suitable
collection). You can now derive that abstract class into two concrete classes - PieDisplay and
BarDisplay and now one of these two concrete classes can be chosen inside a DisplayFactory class
depending upon whether the number of records.

abstract class DisplayRecords{


private Vector recordsToDisplay;
public DisplayRecords(Vector records){
recordsToDisplay = records; }
abstract public Panel display();
...
...
}

class PieDisplay extends DisplayRecords{


...
public PieDisplay(Vector records){
super(records); }
public Panel display(){
//... implementation of pie graph display
... }
...
}

class BarDisplay extends DisplayRecords{


...
public BarDisplay(Vector records){
super(records); }
public Panel display(){
//... implementation of bar graph display
... }
...
}

//...Factory class to make a choice


class DisplayFactory{
...
private DisplayRecords displayRecords;
public DisplayRecords getDisplay(Vector records){
//...building the display
if(records.size() <=5 )
displayRecords = new PieDisplay(records);
else displayRecords = new BarDisplay(records);
return displayRecords;}
...
}

Prototype Design Pattern - this design pattern is used in cases where the instance creation of the class
is very complex and/or time consuming so instead of creating new objects everytime we copy the
already existing original instance and modify the properties of that instance as required. For example:
suppose you have created an object by executing many time consuming database queries and if the
new objects can be constructed by modifying the queried data (especially in the cases where you read
the DB to create various kind of reports) then you would certainly not like to fire all the queries all
over again to create new objects. Instead copying the original instance and modifying the copied data
to suit the requirements of the new report will be a better option here.

How to copy an alraedy existing instance? You can use clone method to do that for you. Not sure how
to use Cloning? Read this article to have a understanding of what Cloning is all about and how can you
implement Shallow Cloning and Deep Cloning -Cloning in Java >>
The limitations of this design pattern is that you may come across some classes where you may not
implement cloning - for instance, if the classes are not new instead they are already existing and being
widely used, if the classes contain objects which can't implement Serializable interafce, or some other
possible reason which may stop the classes to become Cloneable. This completes our discussion of the
popular Creational Design Patterns.

Lastly, you may like to summarize all five creational design patterns. Here is a quick briefing:-

Singleton Design Pattern - used to ensure that there is only one global instance shared by all the
consumers. It's normally implemented by having a static field which is assigned to the global instance
on its first use.

Factory Design Pattern - used to choose and return an an instance based on some passed parameters.
The common base class is used as the return type for all the descendants instances.

Abstract Factory Design Pattern - it provides one level higher abstraction that the Factory Design
Pattern and it's used to return one of the many groups based on some passed parameter. These groups
are normally implemented using Factory Design Pattern. That means Abstract Factory normally returns
Factory :-)

Builder Design Pattern - used for assembing and returing a set of objects based on some passed
parameters. The selection is normally made usnig a Factory and the assembly is made by extending
common abstract base class.

Prototype Design Pattern - used when instantiation of a class is very complex and/or time-consuming.
Instead of direct instantiation and already existing instance is Cloned and the necessary changes and
made to the cloned copy.

You might also like