The factory method pattern is an object-oriented design pattern to implement the concept of factories. Like other creational patterns, it deals with the problem of creating objects (products) without specifying the exact class of object that will be created. The creation of an object often requires complex processes not appropriate to include within a composing object. The object’s creation may lead to a significant duplication of code, may require information not accessible to the composing object, may not provide a sufficient level of abstraction, or may otherwise not be part of the composing object’s concerns. The factory method design pattern handles these problems by defining a separate method for creating the objects, which subclasses can then override to specify the derived type of product that will be created.
Factory pattern comes into creational design pattern category, the main objective of the creational pattern is to instantiate an object and in Factory Pattern an interface is responsible for creating the object but the sub classes decides which class to instantiate. It is like the interface instantiate the appropriate sub-class depending upon the data passed. Here in this article we will understand how we can create an Factory Pattern in Java
The essence of the Factory method Pattern is to “Define an interface for creating an object, but let the subclasses decide which class to instantiate. The Factory method lets a class defer instantiation to subclasses
Use the factory pattern when:
- The creation of the object precludes reuse without significantly duplicating code.
- The creation of the object requires access to information or resources not appropriate to contain within the composing object.
- The lifetime management of created objects needs to be centralised to ensure consistent behavior.
printSomething
.java
package techartifact.pattern.factory; public abstract class PrintSomething { public abstract void printTech(); }
Now we will have the concrete implementations of the PrintSomething
class, JavaTech
and J2eeTech
, each providing a much simplified implementation for the printTech() method.
JavaTech.java
package techartifact.pattern.factory; public class JavaTech extends PrintSomething { @Override public void printTech() { System.out.println("this is java technology"); } }
We will having one more class for j2eeTech for j2ee technology.
J2eeTech.java
package techartifact.pattern.factory; public class J2eeTech extends PrintSomething { public void printTech() { System.out.println("this is j2ee technology"); } }
Now let us come to the core implementation, the Factory
class itself. The PrintFactory
class has one static method called showPrint()
which the clients can invoke to get the PrintSomething
object. Note the return type of the method, it is neither JavaTech
nor J2eeTech
, but the super type of the both, i.e, PrintSomething
. Whether the return type of method is JavaTech
or J2eeTech
is decided based on the input operating system.
PrintFactory.java
package techartifact.pattern.factory; public class PrintFactory { public static PrintSomething showPrint(String os){ if (os.equals("Java")) { return new JavaTech(); } else if (os.equals("J2ee")) { return new J2eeTech(); } return null } }
In this we can makes use of the above PrintFactory
class. The client is un-aware of the fact there is multiple implementations of the PrintSomething
class. It accesses the printTech() operation through a single unified type PrintSomething
FactoryClient.java
package techartifact.pattern.factory; public class FactoryClient { public static void main(String[] args) { PrintSomething psJava =PrintFactory.showPrint("Java"); psJava.printTech(); PrintSomething psJ2ee = PrintFactory.showPrint("J2ee"); psJ2ee.printTech(); } }