Introduction to the Factory Design Pattern

Factory design pattern is a creational pattern providing an efficient way of creating objects by providing an abstracted layer separating the creation logic from the client code. Per wikipedia, the Factory design pattern is one of the twenty-three well-known "Gang of Four" design patterns that describe how to solve recurring design problems to design flexible and reusable object-oriented software, that is, objects that are easier to implement, change, test, and reuse.

The Factory Method design pattern solves problems like:

  • How can an object be created so that subclasses can redefine which class to instantiate?
  • How can a class defer instantiation to subclasses?

Creating an object directly within the class that requires (uses) the object is inflexible because it commits the class to a particular object and makes it impossible to change the instantiation independently from (without having to change) the class.

The Factory Method design pattern describes how to solve such problems:

  • Define a separate operation (factory method) for creating an object.
  • Create an object by calling a factory method. This enables writing of subclasses to change the way an object is created (to redefine which class to instantiate).
The Poisson Distribution Distribution Cover

Given below are sample codes implementing the UML diagram above -

/**
Product interface
**/
public interface Travel {
 public void bookTravel(String travel_id);
 public void cancelTravel(String travel_id);
 public void displayTravelInfo();
}
/**
Libray Classes - concrete implementations of Product
**/
public class BusTravel implements Travel {
 @Override
 public void bookTravel(String travel_id) {
  System.out.println("Booking travel...");
 
 }
 
 @Override
 public void cancelTravel(String travel_id) {
  System.out.println("Cancelling travel...");
 }
 
 @Override
 public void displayTravelInfo(String travel_id) {
  System.out.println("Displaying travel info...");
 }
}
 
public class TrainTravel implements Travel {
 @Override
 public void bookTravel(String travel_id) {
  System.out.println("Booking travel...");
 
 }
 
 @Override
 public void cancelTravel(String travel_id) {
  System.out.println("Cancelling travel...");
 }
 
 @Override
 public void displayTravelInfo(String travel_id) {
  System.out.println("Displaying travel info...");
 }
}
 
 
public class FlightTravel implements Travel {
 @Override
 public void bookTravel(String travel_id) {
  System.out.println("Booking travel...");
 
 }
 
 @Override
 public void cancelTravel(String travel_id) {
  System.out.println("Cancelling travel...");
 }
 
 @Override
 public void displayTravelInfo(String travel_id) {
  System.out.println("Displaying travel info...");
 }
}
 
/**
Creator abstract class
**/
public abstract class TravelCreator() {
 public abstract Travel getTravel();
}
 
/**
Concrete Product Creator
**/
public class BusTravelCreator extends TravelCreator() {
 @Override
 public Travel getTravel() {
  return new BusTravel();
 }
}
 
public class TrainTravelCreator extends TravelCreator() {
 @Override
 public Travel getTravel() {
  return new TrainTravel();
 }
}
 
public class FlightTravelCreator extends TravelCreator() {
 @Override
 public Travel getTravel() {
  return new FlightTravel();
 }
}
 
 
/**
Client Code
**/
public class TravelBooking {
 private final TravelCreator creator;
 
 public TravelBooking(TravelCreator creator) {
  this.creator = creator;
 }
 
 public void displayTravelInfo() {
  creator.getTravel().displayTravelInfo();
 }
 
}
 
TravelBooking tb_bus = new TravelBooking(new BusTravelCreator());
TravelBooking tb_train = new TravelBooking(new TrainTravelCreator());
TravelBooking tb_flight = new TravelBooking(new FlightTravelCreator());
/**
Product interface
**/
public interface Travel {
 public void bookTravel(String travel_id);
 public void cancelTravel(String travel_id);
 public void displayTravelInfo();
}
/**
Libray Classes - concrete implementations of Product
**/
public class BusTravel implements Travel {
 @Override
 public void bookTravel(String travel_id) {
  System.out.println("Booking travel...");
 
 }
 
 @Override
 public void cancelTravel(String travel_id) {
  System.out.println("Cancelling travel...");
 }
 
 @Override
 public void displayTravelInfo(String travel_id) {
  System.out.println("Displaying travel info...");
 }
}
 
public class TrainTravel implements Travel {
 @Override
 public void bookTravel(String travel_id) {
  System.out.println("Booking travel...");
 
 }
 
 @Override
 public void cancelTravel(String travel_id) {
  System.out.println("Cancelling travel...");
 }
 
 @Override
 public void displayTravelInfo(String travel_id) {
  System.out.println("Displaying travel info...");
 }
}
 
 
public class FlightTravel implements Travel {
 @Override
 public void bookTravel(String travel_id) {
  System.out.println("Booking travel...");
 
 }
 
 @Override
 public void cancelTravel(String travel_id) {
  System.out.println("Cancelling travel...");
 }
 
 @Override
 public void displayTravelInfo(String travel_id) {
  System.out.println("Displaying travel info...");
 }
}
 
/**
Creator abstract class
**/
public abstract class TravelCreator() {
 public abstract Travel getTravel();
}
 
/**
Concrete Product Creator
**/
public class BusTravelCreator extends TravelCreator() {
 @Override
 public Travel getTravel() {
  return new BusTravel();
 }
}
 
public class TrainTravelCreator extends TravelCreator() {
 @Override
 public Travel getTravel() {
  return new TrainTravel();
 }
}
 
public class FlightTravelCreator extends TravelCreator() {
 @Override
 public Travel getTravel() {
  return new FlightTravel();
 }
}
 
 
/**
Client Code
**/
public class TravelBooking {
 private final TravelCreator creator;
 
 public TravelBooking(TravelCreator creator) {
  this.creator = creator;
 }
 
 public void displayTravelInfo() {
  creator.getTravel().displayTravelInfo();
 }
 
}
 
TravelBooking tb_bus = new TravelBooking(new BusTravelCreator());
TravelBooking tb_train = new TravelBooking(new TrainTravelCreator());
TravelBooking tb_flight = new TravelBooking(new FlightTravelCreator());


Testingfly

Testingfly is my spot for sharing insights and experiences, with a primary focus on tools and technologies related to test automation and governance.

Comments

Want to give your thoughts or chat about more ideas? Feel free to leave a comment here.

Instead of authenticating the giscus application, you can also comment directly on GitHub.

Related Articles

Testing iFrames using Playwright

Automated testing has become an integral part of web application development. However, testing in Safari, Apple's web browser, presents unique challenges due to the browser's strict Same-Origin Policy (SOP), especially when dealing with iframes. In this article, we'll explore known issues related to Safari's SOP, discuss workarounds, and demonstrate how Playwright, a popular automation testing framework, supports automated testing in this context.

Overview of SiteCore for Beginners

Sitecore is a digital experience platform that combines content management, marketing automation, and eCommerce. It's an enterprise-level content management system (CMS) built on ASP.NET. Sitecore allows businesses to create, manage, and publish content across all channels using simple tools.