^

Design Pattern

Design Patterns are a cornerstone of today's software development. Using design patterns, creation and maintainability of Java applications can be improved and their cost can be reduced. In 1994, four authors, Erich Gamma, Richard Helm, Ralph Johnson and John Vpissides, published a book titled "Design Patterns - Elements of Reusable Object-Oriented Software". This book introduced the concept of design patterns in software development.
These four authors are known as Gang of Four (GOF). According to them, design patterns are based on the following principles of Object Oriented Design(OOD):
  • Program to an interface, not an implementation.
  • Prefer object composition over inheritance
Some useful definitions of design patterns are:
  • "Design Patterns are recurring solutions to design problems, you see over and over"
  • "Design Patterns constitute a set of rules describing how to accomplish certain tasks in the realm of software development".
  • •"Patterns identify and specify abstractions that are above the level of single classes and instances".

Types of Design Patterns

Authors divided design patterns into three types:
  • Creational Patterns:Create objects rather than instantiating objects directly using new operator.
  • Structural Patterns: Help to compose group of objects in the larger structures.
  • Behavioral Patterns: Help to define communication between the objects and how flow is controlled.
The most commonly used patterns are subject of discussion in this book.

Factory Pattern

It is commonly used design pattern in Java. It comes under creational pattern. It provides a better way to create an object depending upon data provided to it. In this pattern, objects are created without disclosing the creational logic. It can return objects of different types using a common interface. The factory pattern is discussed below using the class diagram and program:
Class Diagram:
interface shape
        {
        void draw();
        }
class circle implements shape
        {
        public void draw()
        {
        System.out.println("Drawing Circle");
        }
        }
class square implements shape
        {
        public void draw()
        {
        System.out.println("Drawing Square");
        }
        }
class rectangle implements shape
        {
        public void draw()
        {
        System.out.println("Drawing Rectangle");
        }
        }
        class shapeFactory
        {
        shape getobject(String type)
        {
        if(type==null)
        {
        return (null);
        }
        else if(type.equals("circle"))
        {
        return(new circle());
        }
        else if(type.equals("square"))
        {
        return(new square());
        }
        else if(type.equals("rectangle"))
        {
        return(new rectangle());
        }
        else
        {
        return(null);
        }
        }
        }
        //Using the Factory Class
class FPUser
{
public static void main(String args[])
{
shapeFactory sf=new shapeFactory();
shape r=sf.getobject("rectangle");
r.draw();//Drawing Rectangle
sf.getobject("square").draw();//Drawing Square
circle c=(circle)sf.getobject("circle");
c.draw();//Drawing Circle
}
}
         
Output
  Drawing Rectangle 
  Drawing Square
  Drawing Circle 
         
Explanation
In the above program, class ShapeFactory consists of a factory method getObject(), which accepts a string as an argument and returns object of the corresponding class. Its return type is Shape (an interface) that is implemented by Circle, Square and Rectangle classes, however this factory method can return reference of a class that implements interface according to its return type.

Abstract Factory Design Pattern

Abstract factory design pattern is a creational design pattern. It is an extension of factory pattern. It is considered as another layer of abstraction over factory pattern. It means that abstract factory returns the factory of classes, whereas factory method returns one of the various sub-classes. Consider the following class diagram for better understanding:
Class Diagram
According to the above class diagram, classes Cpp and Java implement Syllabus interface and classes CppAuthors and JavaAuthors, implement Authors interface. Factory classes, Syllabus Factory and Authors Factory, implement Syllabus Authors interface. Factory User class calls getFactory() method of the Factory Producer class to instantiate further factory classes.
Implementation
interface syllabus
{
void display();
}
class cpp implements syllabus
{
public void display()
{
System.out.println("Array,Pointer,Loops,Class");
}
}
class java implements syllabus
{
public void display()
{
System.out.println("Thread,Interface,Exception");
}
}
interface authors
{
void showlist();
}
class cppauthors implements authors
{
public void showlist()
{
System.out.println("Yashwant Kant, Ravichandran");
}
}
class javaauthors implements authors
{
public void showlist()
{
System.out.println("James Gosling , Rajesh Bansal");
}
}
interface syllabusauthors
{
syllabus getsyllabus(String subjects);
authors getauthors(String Book);
}
class syllabusfactory implements syllabusauthors
{
public syllabus getsyllabus(String Subject)
{
if(Subject.equals("cpp"))
{
return new cpp();
}
else if(subject.equals("java"))
{
return new java();
}
else
{
return null;
}
}
public authors getauthors(String Book)
{
return null;
}
}
class authorsfactory implements syllabusauthors
{
public authors getauthors(string book)
{
if(book.equals("cpp"))
{
return new cppauthors();
}
else
if(book.equals("java"))
{
return new javaauthors();
}
else
{
return null;
}
}
public syllabus getsyllabus(String Subject)
{
return null;
}
}
class factoryproducer
{
static syllabusauthors getfactory(String type)
{
if(type.equals("syllabus"))
return new syllabusfactory();
else if(type.equals("authors"))
return new authorsfactory();
else
return null;
}
}
public class factoryuser
{
syllabusauthors syl=factoryproducer.getfactory("syllabus");
syllabus cpp=syl.getsyllabus("cpp");
cpp.display();
syllabus java=syl.getsyllabus("java");
java.display();
syllabusauthors auth=factoryprocedure.getfactory("authors");
authors cpp_auth=auth.getauthors("cpp");
cpp_auth.showlist();
authors java_auth=auth.getauthors("cpp");
java_auth.showlist();

}
       
Output
 Array, Pointers, Loops, Classes Threads, Interface, Exceptions Yashwant Kant., Ravichandran James Gosling, Rajesh Bansal

       

Adapter Design Pattern

The adapter design pattern is a structural pattern. It is used to make two unrelated interfaces work together. Some times a class library cannot be used because its interface is not compatible with the interface required by an application. In this case, you need to create an adapter class which makes them work together. An adapter class allows you to reuse the existing code without changing it. For example, your mobile phone charger plays the role of an adapter because it takes 220 volt supply and gives 9 volt supply to charge your mobile.
As the above class diagram shows, class Result acts as an adapter class which implements IResult interface. Now, class College can use Result class as an adapter to get percentage and grade. But class Result uses Total class to get total marks to find the percentage and grade of a student. Consider the following program to understand how adapter design pattern can be used to solve real life problems:

Singleton Design Pattern

Singleton design pattern is a creational design pattern. A singleton is simply a class which can be instantiated exactly once. There are two ways to implement singleton design pattern, both use private constructors and a public static field of class type that contains this field to provide access to the sole instance,
  1. In one approach, a final & static field of same class type is used as shown in the program below:
class userlibrary
{
public static final userlibrary lib=new library();
private userlibrary(){}
public double getsquare(double v)
{
return v*v;
}
public double getpi()
{
return 3.14;
}
public double getcylindervol(double r,double h)
{
return getpi()* getsquare(r)*h;
}
}
public class designptrn_singleton
{
public static void main(String[] args)
{
userlibrary lib=userlibrary.lib;
double sq=lib.getsquare(10);
double cylvol=lib.getcylindervol(10,20);
System.out.println("Square="+sq+"cyl . volume="+cylvol);
}
}
        
   Output
     Square=100.0 Cyl. Volume=6280.0 
Explanation
In the above program, line number 14 generates error because UserLibrary class cannot be instantiated due to its private constructor. In line number 2, UserLibrary class is instantiated with static, final and public modifiers and its reference is obtained in main function() in line number 18 to call the methods getSquare() and getCylinder Vol().
2. In the second approach, a public & static factory method is used to return the reference of a UserLibrary class object which is declared as private, static and final, as shown in the program below:
class userlibrary
{
private static final userlibrary lib=new library();
private userlibrary(){}
public static userlibrary getinstance()
{
return lib;
}
public double getsquare(double v)
{
return v*v;
}
public double getpi()
{
return 3.14;
}
public double getcylindervol(double r,double h)
{
return getpi()* getsquare(r)*h;
}
}
public class designptrn_singleton
{
public static void main(String[] args)
{
userlibrary lib=userlibrary.getinstance;
double sq=lib.getsquare(10);
double cylvol=lib.getcylindervol(10,20);
System.out.println("Square="+sq+"cyl . volume="+cylvol);
}
}
       
  Output
    Square=100.0 Cyl. Volume=6280.0

       
Explanation
In the above program, in line number 3, lib is declared as a private field which refers to the instance of UserLibrary class. It is not accessible to the outside world, so a static factory method, getInstance(), is introduced to return its reference. Line number 21 calls getInstance() to obtain the reference for calling the methods that belong to such instance.

About the Author
Rajesh K. Bansal (SCJP-Sun Certified Java Programmer)
20 Years experience in Training & Development. Founder of realJavaOnline.com, loves coding in Java(J2SE, J2EE), C++,PHP, Python, AngularJS, Android,MERN Stack(MongoDB,Express,ReactJS,NodeJS). If you like tutorials and want to know more in depth about Java , buy his book "Real Java" available on amazon.in.
#Email : bcebti@gmail.com #Contact : 98722-46056
Available on Amazon
Card image cap
Under the guidance of Founder & Author of "realJavaOnline.com". M:9872246056
Card image cap