Category: 03. Design Patterns

https://cdn-icons-png.freepik.com/512/8361/8361102.png

  • Singleton Pattern

    Singleton pattern is one of the simplest design patterns in Java. This type of design pattern comes under creational pattern as this pattern provides one of the best ways to create an object.

    This pattern involves a single class which is responsible to create an object while making sure that only single object gets created. This class provides a way to access its only object which can be accessed directly without need to instantiate the object of the class.

    Implementation

    We’re going to create a SingleObject class. SingleObject class have its constructor as private and have a static instance of itself.

    SingleObject class provides a static method to get its static instance to outside world. SingletonPatternDemo, our demo class will use SingleObject class to get a SingleObject object.

    Singleton Pattern UML Diagram

    Step 1

    Create a Singleton Class.

    SingleObject.java

    public class SingleObject {
    
       //create an object of SingleObject
       private static SingleObject instance = new SingleObject();
    
       //make the constructor private so that this class cannot be
       //instantiated
       private SingleObject(){}
    
       //Get the only object available
       public static SingleObject getInstance(){
    
      return instance;
    } public void showMessage(){
      System.out.println("Hello World!");
    } }

    Explore our latest online courses and learn new skills at your own pace. Enroll and become a certified expert to boost your career.

    Step 2

    Get the only object from the singleton class.

    SingletonPatternDemo.java

    public class SingletonPatternDemo {
       public static void main(String[] args) {
    
    
      //illegal construct
      //Compile Time Error: The constructor SingleObject() is not visible
      //SingleObject object = new SingleObject();
      //Get the only object available
      SingleObject object = SingleObject.getInstance();
      //show the message
      object.showMessage();
    } }

    Step 3

    Verify the output.

    Hello World!
    
  • Abstract Factory Pattern

    Abstract Factory patterns work around a super-factory which creates other factories. This factory is also called as factory of factories. This type of design pattern comes under creational pattern as this pattern provides one of the best ways to create an object.

    In Abstract Factory pattern an interface is responsible for creating a factory of related objects without explicitly specifying their classes. Each generated factory can give the objects as per the Factory pattern.

    Implementation

    We are going to create a Shape interface and a concrete class implementing it. We create an abstract factory class AbstractFactory as next step. Factory class ShapeFactory is defined, which extends AbstractFactory. A factory creator/generator class FactoryProducer is created.

    AbstractFactoryPatternDemo, our demo class uses FactoryProducer to get a AbstractFactory object. It will pass information (CIRCLE / RECTANGLE / SQUARE for Shape) to AbstractFactory to get the type of object it needs.

    Abstract Factory Pattern UML Diagram

    Step 1

    Create an interface for Shapes.

    Shape.java

    public interface Shape {
       void draw();
    }

    Explore our latest online courses and learn new skills at your own pace. Enroll and become a certified expert to boost your career.

    Step 2

    Create concrete classes implementing the same interface.

    RoundedRectangle.java

    public class RoundedRectangle implements Shape {
       @Override
       public void draw() {
    
      System.out.println("Inside RoundedRectangle::draw() method.");
    } }

    RoundedSquare.java

    public class RoundedSquare implements Shape {
       @Override
       public void draw() {
    
      System.out.println("Inside RoundedSquare::draw() method.");
    } }

    Rectangle.java

    public class Rectangle implements Shape {
       @Override
       public void draw() {
    
      System.out.println("Inside Rectangle::draw() method.");
    } }

    Step 3

    Create an Abstract class to get factories for Normal and Rounded Shape Objects.

    AbstractFactory.java

    public abstract class AbstractFactory {
       abstract Shape getShape(String shapeType) ;
    }

    Step 4

    Create Factory classes extending AbstractFactory to generate object of concrete class based on given information.

    ShapeFactory.java

    public class ShapeFactory extends AbstractFactory {
       @Override
       public Shape getShape(String shapeType){    
    
      if(shapeType.equalsIgnoreCase("RECTANGLE")){
         return new Rectangle();         
      }else if(shapeType.equalsIgnoreCase("SQUARE")){
         return new Square();
      }	 
      return null;
    } }

    RoundedShapeFactory.java

    public class RoundedShapeFactory extends AbstractFactory {
       @Override
       public Shape getShape(String shapeType){    
    
      if(shapeType.equalsIgnoreCase("RECTANGLE")){
         return new RoundedRectangle();         
      }else if(shapeType.equalsIgnoreCase("SQUARE")){
         return new RoundedSquare();
      }	 
      return null;
    } }

    Step 5

    Create a Factory generator/producer class to get factories by passing an information such as Shape

    FactoryProducer.java

    public class FactoryProducer {
       public static AbstractFactory getFactory(boolean rounded){   
    
      if(rounded){
         return new RoundedShapeFactory();         
      }else{
         return new ShapeFactory();
      }
    } }

    Step 6

    Use the FactoryProducer to get AbstractFactory in order to get factories of concrete classes by passing an information such as type.

    AbstractFactoryPatternDemo.java

    public class AbstractFactoryPatternDemo {
       public static void main(String[] args) {
    
      //get shape factory
      AbstractFactory shapeFactory = FactoryProducer.getFactory(false);
      //get an object of Shape Rectangle
      Shape shape1 = shapeFactory.getShape("RECTANGLE");
      //call draw method of Shape Rectangle
      shape1.draw();
      //get an object of Shape Square 
      Shape shape2 = shapeFactory.getShape("SQUARE");
      //call draw method of Shape Square
      shape2.draw();
      //get shape factory
      AbstractFactory shapeFactory1 = FactoryProducer.getFactory(true);
      //get an object of Shape Rectangle
      Shape shape3 = shapeFactory1.getShape("RECTANGLE");
      //call draw method of Shape Rectangle
      shape3.draw();
      //get an object of Shape Square 
      Shape shape4 = shapeFactory1.getShape("SQUARE");
      //call draw method of Shape Square
      shape4.draw();
      
    } }

    Step 7

    Verify the output.

    Inside Rectangle::draw() method.
    Inside Square::draw() method.
    Inside RoundedRectangle::draw() method.
    Inside RoundedSquare::draw() method.
    
  • Factory Pattern

    Factory pattern is one of the most used design patterns in Java. This type of design pattern comes under creational pattern as this pattern provides one of the best ways to create an object.

    In Factory pattern, we create object without exposing the creation logic to the client and refer to newly created object using a common interface.

    Implementation

    We’re going to create a Shape interface and concrete classes implementing the Shape interface. A factory class ShapeFactory is defined as a next step.

    FactoryPatternDemo, our demo class will use ShapeFactory to get a Shape object. It will pass information (CIRCLE / RECTANGLE / SQUARE) to ShapeFactory to get the type of object it needs.

    Factory Pattern UML Diagram

    Step 1

    Create an interface.

    Shape.java

    public interface Shape {
       void draw();
    }

    Explore our latest online courses and learn new skills at your own pace. Enroll and become a certified expert to boost your career.

    Step 2

    Create concrete classes implementing the same interface.

    Rectangle.java

    public class Rectangle implements Shape {
    
       @Override
       public void draw() {
    
      System.out.println("Inside Rectangle::draw() method.");
    } }

    Square.java

    public class Square implements Shape {
    
       @Override
       public void draw() {
    
      System.out.println("Inside Square::draw() method.");
    } }

    Circle.java

    public class Circle implements Shape {
    
       @Override
       public void draw() {
    
      System.out.println("Inside Circle::draw() method.");
    } }

    Step 3

    Create a Factory to generate object of concrete class based on given information.

    ShapeFactory.java

    public class ShapeFactory {
    	
       //use getShape method to get object of type shape 
       public Shape getShape(String shapeType){
    
      if(shapeType == null){
         return null;
      }		
      if(shapeType.equalsIgnoreCase("CIRCLE")){
         return new Circle();
         
      } else if(shapeType.equalsIgnoreCase("RECTANGLE")){
         return new Rectangle();
         
      } else if(shapeType.equalsIgnoreCase("SQUARE")){
         return new Square();
      }
      
      return null;
    } }

    Step 4

    Use the Factory to get object of concrete class by passing an information such as type.

    FactoryPatternDemo.java

    public class FactoryPatternDemo {
    
       public static void main(String[] args) {
    
      ShapeFactory shapeFactory = new ShapeFactory();
      //get an object of Circle and call its draw method.
      Shape shape1 = shapeFactory.getShape("CIRCLE");
      //call draw method of Circle
      shape1.draw();
      //get an object of Rectangle and call its draw method.
      Shape shape2 = shapeFactory.getShape("RECTANGLE");
      //call draw method of Rectangle
      shape2.draw();
      //get an object of Square and call its draw method.
      Shape shape3 = shapeFactory.getShape("SQUARE");
      //call draw method of square
      shape3.draw();
    } }

    Step 5

    Verify the output.

    Inside Circle::draw() method.
    Inside Rectangle::draw() method.
    Inside Square::draw() method.
    
  • Overview

    Design patterns represent the best practices used by experienced object-oriented software developers. Design patterns are solutions to general problems that software developers faced during software development. These solutions were obtained by trial and error by numerous software developers over quite a substantial period of time.

    What is Gang of Four (GOF)?

    In 1994, four authors Erich Gamma, Richard Helm, Ralph Johnson and John Vlissides published a book titled Design Patterns – Elements of Reusable Object-Oriented Software which initiated the concept of Design Pattern in Software development.

    These authors are collectively known as Gang of Four (GOF). According to these authors design patterns are primarily based on the following principles of object orientated design.

    • Program to an interface not an implementation
    • Favor object composition over inheritance

    Usage of Design Pattern

    Design Patterns have two main usages in software development.

    Common platform for developers

    Design patterns provide a standard terminology and are specific to particular scenario. For example, a singleton design pattern signifies use of single object so all developers familiar with single design pattern will make use of single object and they can tell each other that program is following a singleton pattern.

    Best Practices

    Design patterns have been evolved over a long period of time and they provide best solutions to certain problems faced during software development. Learning these patterns helps unexperienced developers to learn software design in an easy and faster way.

    Explore our latest online courses and learn new skills at your own pace. Enroll and become a certified expert to boost your career.

    Types of Design Patterns

    As per the design pattern reference book Design Patterns – Elements of Reusable Object-Oriented Software , there are 23 design patterns which can be classified in three categories: Creational, Structural and Behavioral patterns. We’ll also discuss another category of design pattern: J2EE design patterns.

    S.N.Pattern & Description
    1Creational Patterns
    These design patterns provide a way to create objects while hiding the creation logic, rather than instantiating objects directly using new operator. This gives program more flexibility in deciding which objects need to be created for a given use case.
    2Structural Patterns
    These design patterns concern class and object composition. Concept of inheritance is used to compose interfaces and define ways to compose objects to obtain new functionalities.
    3Behavioral Patterns
    These design patterns are specifically concerned with communication between objects.
    4J2EE Patterns
    These design patterns are specifically concerned with the presentation tier. These patterns are identified by Sun Java Center.