In object-oriented programming, the factory design pattern is a creational design pattern that encapsulates the object-creational logic. The factory pattern relies on factory methods to create objects, and the caller is unaware of the classes of resulting objects the factory pattern returns.
Stationery stationery = ProductFactory.getProduct(stationeryName);
The
An ideal situation is when you have an interface and several classes that implement the interface (a typical object-oriented implementation). Based on factory method implementation logic, the factory method caller will receive objects of these subclasses. Therefore, the factory pattern is most suitable for creating objects dynamically at run-time.
In practice, let's take stationery as an example. Stationery can consider a product category. Pens, books, paper clips, etc., are sub-categories that belong to stationery. Therefore, stationery is a candidate for our interface, and sub-categories can represent subclasses that implement our interface.
The implementation is a factory for subclasses. That's what it is. The factory pattern returns one of the subclasses based on callers' requirements.
Let's look at a code example. We have a parent interface,
interface Stationary{
public String getProductInfo(){}
}
The Book class implements the Product interface with its properties pages and price. It also overrides parents'
class Book implements Stationery{
private int pages;
private BigDecimal price;
public Book(int pages, BigDecimal price){
this.pages = pages ;
this.price = price;
}
public String getProductInfo(){
return "This book costs: $"+price+" and it has :" +pages + "pages";
}
}
The
class Pen implements Stationery{
private String color;
public BigDecimal price;
public Pen(String color, BigDecimal price){
this.price = price;
this.color = color;
}
public String getProductInfo(){
return "This pen costs: $"+price+" and it writes in :" +color;
}
}
The factory class is self-explanatory. The best practice is using an enum class to hold class names instead of hardcoded ones. If you are not new to object-oriented programming, you will notice that the
class ProductFactory{
public static Product getProduct(String product){
if("Book".equalsIgnoreCase(product)){
return new Book(500, new BigDecimal("24.95"));
}
if("Pen".equalsIgnoreCase(product)){
return new Pen("Blue", new BigDecimal("0.95"));
}
else
return null;
}
}
Here is the code to test the implemented concept.
public class FactoryPattern{
public static void main(String args[]){
Stationary book = ProductFactory.getProduct("Book");
System.out.println(book.getProductInfo());
Stationary pen = ProductFactory.getProduct("Pen");
System.out.println(pen.getProductInfo());
}
}
Note that we request objects from the factory twice. In both requests, we receive objects of the type
The factory design pattern encapsulates object-creational logic from its users by providing factory methods that instantiate objects based on arguments the factory methods receive. The resulting objects are the parent class type, and the implementing class is determined by the argument passed to the factory method. These behaviors make the factory design pattern ideal for creating objects dynamically at run-time.