Java Design Pattern - Easy Learning with Examples


Design pattern is a general term that represents reusable solutions with best practices used by object-oriented developers for different types of problems. It defines the concept of template of solving a problem that can be used by many different situations that help to define the system architecture
 
In 1994, four authors - Erich Gamma, Richard Helm, Ralph Johnson and John Vlissides published a book named "Design Patterns - Elements of Reusable Object-Oriented Software" that introduced the concept of Design Pattern in Software development. These authors are collectively known as Gang of Four (GOF). According to them design patterns are primarily based on following principles of object orientated design
  • Program to an interface not an implementation
  • Favor object composition over inheritance
Since old object oriented programming, there are mainly three categories of design patterns which are further divided into sub-types based on their functions and characteristics. The three main categories of design patterns are:
    - Creational Design Patterns
    - Structural
Design Patterns and
    - Behavioral
Design Patterns 

There is another category of design pattern specifically concerned with the presentation tier, identified by Sun Java Center is called
    - J2EE design patterns
Design Patterns based on main categories are as follows:
1. Creational Design Patterns
  1. Factory Pattern
  2. Abstract Factory Pattern
  3. Singleton Pattern
  4. Object Pool Pattern
  5. Prototype Pattern
  6. Builder Pattern
2. Structural Design Patterns
  1. Adapter Pattern
  2. Bridge Pattern
  3. Composite Pattern
  4. Decorator Pattern
  5. Facade Pattern
  6. Flyweight Pattern
  7. Private Class Data
  8. Proxy Pattern
3. Behavioral Design Patterns
  1. Chain Of Responsibility Pattern
  2. Command Pattern
  3. Interpreter Pattern
  4. Iterator Pattern
  5. Mediator Pattern
  6. Memento Pattern
  7. Null Object
  8. Observer Pattern
  9. State Pattern
  10. Strategy Pattern
  11. Template Pattern
  12. Visitor Pattern
4. J2EE Design Patterns 
  1. MVC Pattern
  2. Business Delegate Pattern
  3. Composite Entity Pattern
  4. Data Access Object Pattern
  5. Front Controller Pattern
  6. Intercepting Filter Pattern
  7. Service Locator Pattern
  8. Transfer Object Pattern
Different design patterns are described below with brief descriptions and simple examples

1. Creational Design Pattern

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.

        1.1. Factory Pattern: Creates an instance of several derived classes

        Step 1: Create an interface.
        Shape.java
        public interface Shape {
           void draw();
        }
        
        Step 2: Create concrete classes implementing the same interface.
        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("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("SQUARE");
        
              //call draw method of Rectangle
              shape2.draw();
           }
        }
        
        Step 5 Verify the output.
        Inside Circle::draw() method.
        Inside Square::draw() method.
        

        1.2. Abstract Factory Pattern: Creates an instance of several families of classes

        Step 1: Create an interface for Shapes and Round cornered shapes.
        Shape.java
        public interface Shape {
           void draw();
        }
        
        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 rounded shape factory
              AbstractFactory shapeFactory = FactoryProducer.getFactory(false);
              //get an object of Shape Rounded Rectangle
              Shape shape1 = shapeFactory.getShape("RECTANGLE");
              //call draw method of Shape Rectangle
              shape1.draw();
              //get an object of Shape Rounded Square 
              Shape shape2 = shapeFactory.getShape("SQUARE");
              //call draw method of Shape Square
              shape2.draw();
              //get rounded 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.
        

        1.3. Singleton Pattern: A class of which only a single instance can exist

        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 to ensure 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!");
           }
        }
        
        Step 2: Get the only object from the singleton class.
        SingletonPatternDemo.java
        public class SingletonPatternDemo {
           public static void main(String[] args) {
              //Get the only object available
              SingleObject object = SingleObject.getInstance();
        
              //Show the message
              object.showMessage();
           }
        }
        
        Step 3
        Verify the output.
        Hello World!
        

        1.4. Object Pool Pattern: Avoid expensive acquisition and release of resources by recycling objects that are no longer in use 

    [Code examples are coming soon...]

        1.5. Prototype Pattern: A fully initialized instance to be copied or cloned

    [Code examples are coming soon...]

        1.6. Builder Pattern: Separates object construction from its representation

    [Code examples are coming soon...]

    2. Structural Design 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.

    [Code examples are coming soon...]

        2.1. Adapter Pattern: Match interfaces of different classes
        2.2. Bridge Pattern: Separates an object's interface from its implementation
        2.3. Composite Pattern: A tree structure of simple and composite objects
        2.4. Decorator Pattern: Add responsibilities to objects dynamically
        2.5. Facade Pattern: A single class that represents an entire subsystem
        2.6. Flyweight Pattern: A fine-grained instance used for efficient sharing
        2.7. Private Class Data: Restricts accessor / mutator access
        2.8. Proxy Pattern: An object representing another object
    • Behavioral Design Patterns
      These design patterns are specifically concerned with communication between objects.
      1. Chain Of Responsibility Pattern: A way of passing a request between a chain of objects
      2. Command Pattern: Encapsulate a command request as an object
      3. Interpreter Pattern: A way to include language elements in a program
      4. Iterator Pattern: Sequentially access the elements of a collection
      5. Mediator Pattern: Defines simplified communication between classes
      6. Memento Pattern: Capture and restore an object's internal state
      7. Null Object: Designed to act as a default value of an object
      8. Observer Pattern: A way of notifying change to a number of classes
      9. State Pattern: Alter an object's behaviour when its state changes
      10. Strategy Pattern: Encapsulates an algorithm inside a class
      11. Template Pattern: Defer the exact steps of an algorithm to a subclass
      12. Visitor Pattern: Defines a new operation to a class without change
    • J2EE Design Patterns
      These design patterns are specifically concerned with the presentation layer along with relevant logics and presentation functionalities. These patterns are identified by Sun Java Center.
      1. MVC Pattern: Wraps-up and connect Model, View and Controller in application architecture. Where Controller is mostly responsible for View and Data layer communication.
      2. Business Delegate Pattern: Used to decouple the presentation layer from the business layer to minimize the number of requests between the client and the business tiers
      3. Composite Entity Pattern: Represents a graph of objects, when that is updated, triggers an update for all other dependent entities in the graph
      4. Data Access Object Pattern: Shortened to DAO is a pattern in which objects are dedicated to the communication with the Data Layer. Often instantiate "SessionFactories" for this purpose and handle all of the logic behind communicating with the database. Standard practice is to create a DAO interface, followed by a concrete class implementing the interface and all methods defined in it.
      5. Front Controller Pattern: Front Controller is the first controller that receives a request that has been sent. Based on the request, it decides which controller is the most adequate to handle it and passes the request to the chosen controller. Front Controller is most often used in Web Applications in the form of a Dispatcher Servlet.
      6. Intercepting Filter Pattern: Filters are used before the request is even passed to relevant controllers for processing. These filters can exist in the form of a Filter Chain. Can include one or multiple filters. Furthermore, they run checks on authorization, authentication, supported browsers, whether the request path violates any constraints and restrictions etc.
      7. Service Locator Pattern: Often seen in Web Applications, this pattern is used to decouple the Service Consumers and the concrete classes like DAO implementations. The pattern looks for the adequate service, saves it in cache storage to reduce the number of requests and therefore the strain on the server and provides the application with their instances.
      8. Transfer Object Pattern: Used to transfer objects with lots of fields and parameters in one go. It employs new objects, used only for transfering purposes, usually passed to the DAO These objects are serializable POJOs. They have fields, their respective getters and setters, and no other logic.








    Comments