1.1 What is Factory Method Pattern?
- Factory Method Design Pattern is a Creational Design Pattern that uses a factory method to deal with problem of creating objects
- It is one of the most commonly used Design Patterns in Java.
- This pattern is also called Virtual Constructor
1.2 Problem (Before Factory Method Pattern)
Imagine that you’re creating a electricity bill generating application. The first version of your app can only handle only Domestic and Commercial Plan. In the next version, the Institutional users want a different Plan. How will you incorporate the change ?

package com.coding.bee.dp.creational.factory.before;
public abstract class Plan {
public abstract double getRate();
public abstract double getFixedCost();
}
package com.coding.bee.dp.creational.factory.before;
public class CommercialPlan extends Plan {
@Override
public double getRate() {
return 5.5;
}
@Override
public double getFixedCost() {
return 10;
}
}
package com.coding.bee.dp.creational.factory.before;
public class DomesticPlan extends Plan {
@Override
public double getRate() {
return 3.5;
}
@Override
public double getFixedCost() {
return 5;
}
}
package com.coding.bee.dp.creational.factory.before;
public class ComputeBill {
public static double getTotalElectricityCharge(Plan plan, int units) {
return plan.getFixedCost() + plan.getRate() * units;
}
}
package com.coding.bee.dp.creational.factory.before;
import java.util.Scanner;
public class GenerateBillClient {
public static void main(String args[]) {
try (Scanner scan = new Scanner(System.in)) {
System.out.print("Enter the name of plan: ");
String planName = scan.nextLine();
System.out.print("Enter number of units: ");
int units = scan.nextInt();
//SuperClass obj = new Subclass();
Plan plan = null;
if (planName.equals("DOMESTIC")) {
plan = new DomesticPlan();
} else if (planName.equals("COMMERCIAL")) {
plan = new CommercialPlan();
}
double cost = ComputeBill.getTotalElectricityCharge(plan, units);
System.out.print("Bill amount for " + planName + " of " + units + " units is : " + cost);
}
}
}
Here each time the client code needs to add new if-else condition and needs to compile again every time we introduce a new subclass. This means that the Product and Client are tightly coupled
1.3 Solution (After Factory Method Pattern)
The solution is to create a static (or Factory) method. Here the Product and Client are loosely-coupled

package com.coding.bee.dp.creational.factory;
public abstract class Plan {
public abstract double getRate();
public abstract double getFixedCost();
}
package com.coding.bee.dp.creational.factory;
public class CommercialPlan extends Plan {
@Override
public double getRate() {
return 5.5;
}
@Override
public double getFixedCost() {
return 10;
}
}
package com.coding.bee.dp.creational.factory;
public class DomesticPlan extends Plan {
@Override
public double getRate() {
return 3.5;
}
@Override
public double getFixedCost() {
return 5;
}
}
package com.coding.bee.dp.creational.factory;
public class InstitutionalPlan extends Plan {
@Override
public double getRate() {
return 7.5;
}
@Override
public double getFixedCost() {
return 20;
}
}
package com.coding.bee.dp.creational.factory;
public class ComputeBill {
public static double getTotalElectricityCharge(Plan plan, int units) {
return plan.getFixedCost() + plan.getRate() * units;
}
}
package com.coding.bee.dp.creational.factory;
public class PlanFactory {
public static Plan getPlan(String planName) {
Plan plan = null;
if (planName.equals("DOMESTIC")) {
plan = new DomesticPlan();
} else if (planName.equals("COMMERCIAL")) {
plan = new CommercialPlan();
}else if (planName.equals("INSTITUTION")) {
plan = new InstitutionalPlan();
}
return plan;
}
}
package com.coding.bee.dp.creational.factory;
import java.util.Scanner;
public class GenerateBillClient {
public static void main(String args[]) {
try (Scanner scan = new Scanner(System.in)) {
System.out.print("Enter the name of plan: ");
String planName = scan.nextLine();
System.out.print("Enter number of units: ");
int units = scan.nextInt();
Plan plan = PlanFactory.getPlan(planName);
double cost = ComputeBill.getTotalElectricityCharge(plan, units);
System.out.print("Bill amount for " + planName + " of " + units + " units is : " + cost);
}
}
}
1.2 When is Factory Method Used?
- The Class/Interface needs to be extended/implemented into Subclasses
- The Class doesn’t know which Subclasses it has to create
- The product implementation tend to change over time, but Client remains unchanged