Thursday, July 28, 2016

Factory design pattern

Factory design pattern in Java one of the core design patterns which is used heavily not only in JDK but also in various Open-Source framework such as Spring, Struts and Apache along with decorator design pattern in Java. Factory Design pattern is based on Encapsulation object-oriented concept. It falls under the Creational design pattern category.

The factory design pattern is used when we have a superclass with multiple subclasses and based on input, we need to return one of the subclasses. This pattern takes out the responsibility of the instantiation of a Class from the client program to the factory class.

Factory Method: Defines an interface for creating an object, but let’s the classes that implement the interface decide which class to instantiate. The Factory method lets a class defer instantiation to sub-classes.
  • creates objects without exposing the instantiation logic to the client.
  • refers to the newly created object through a common interface
 Code Example of Factory Design Pattern in Java:
Let’s see an example of how factory pattern is implemented in Code. Consider a Garment Factory which produces various types of garments like shirt, trousers. The consumers can request for the required types of garments through the factory. However, from consumer’s perspective they are completely unaware of who is creating this object. They just know that the Factory is providing them the required garments.

The below class diagram will give a complete overview of implementation of Factory Pattern:



GarmentType.java
public interface GarmentType {
    String print();
}

Trouser.java
public class Trouser implements GarmentType {
    @Override
    public String print() {
        System.out.println("Trouser Created");
        return "Trouser";
    }
 }

Shirt.java
public class Shirt implements GarmentType {
    @Override
    public String print() {
        System.out.println("Shirt Created");
        return "Shirt";
    }
}

GarmentFactory.java
public class GarmentFactory {
    public static GarmentType createGarments(String selection) {
        if (selection.equalsIgnoreCase("Trouser")) {
            return new Trouser();
        } else if (selection.equalsIgnoreCase("Shirt")) {
            return new Shirt();
        }
        throw new IllegalArgumentException("Selection doesnot exist");
    }
}

Client.java
public class Client {
    public static void main(String[] args) {
        System.out.println("Enter your selection:");
        BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
        String selection = null;
        try {
            selection = br.readLine();
        } catch (IOException e) {
            e.printStackTrace();
        }
        GarmentType objGarmentType = GarmentFactory.createGarments(selection);
        System.out.println(objGarmentType.print());
    }
}

Examples:

JDBC is a good example for this pattern; application code doesn’t need to know what database it will be used with, so it doesn’t know what database-specific driver classes it should use. Instead, it uses factory methods to get Connections, Statements, and other objects to work with. This gives flexibility to change the back-end database without changing your DAO layer.
Below are some examples from the SDK:
valueOf() method which returns object created by factory equivalent to value of parameter passed.
getInstance() method which creates instance of Singleton class.
newInstance() method which is used to create and return new instance from factory method every time called.

Here are some real-time use cases where the Factory Method pattern is particularly effective:

1. Database Connection Pools

Context: In applications that interact with multiple types of databases (e.g., MySQL, PostgreSQL), the database connection pool must create connections specific to each database type.

Example: You might have an abstract DatabaseConnection class and concrete implementations for each type of database. A DatabaseConnectionFactory class can use a factory method to return the correct DatabaseConnection based on the database type specified.

2. Logging Frameworks

Context: Logging frameworks often need to produce different types of logs, such as console logs, file logs, or remote server logs. The exact logging implementation can be selected at runtime.

Example: A Logger interface with concrete implementations like FileLogger and ConsoleLogger. A LoggerFactory can provide the appropriate logger instance based on configuration settings.

3. Document Generation Systems

Context: In systems that generate various types of documents (e.g., PDFs, Word documents, HTML), the factory method can be used to create the correct document type based on user selection.

Example: A Document interface with concrete classes like PDFDocument and WordDocument. A DocumentFactory creates the appropriate document based on the desired type.

 

No comments:

Post a Comment