Category Archives: CREATIONAL DESIGN PATTERN

Abstract Factory Design Pattern

1.1 What is Abstract Factory Pattern?
  • Abstract Factory is a creational design pattern that lets you produce families of related objects without specifying their concrete classes
  • This pattern works around a super-factory which creates other factories. This factory is called factory of factories
1.2  Problem

Imagine that you’re creating a furniture shop simulator. Your code consists of classes that represent:

a) A family of related products, say: Chair + Sofa + Coffee Table.

b) Several variants of this family. For example, products Chair + Sofa + Coffee Table are available in these variants: Modern, Victorian.

You need a way to create individual furniture objects so that they match other objects of the same family. Customers get quite mad when they receive non-matching furniture.

furniture
1.3  Solution
uml-abstract-design-pattern
UML Diagram for Abstract Factory Pattern

Step 1: Declare interfaces for each distinct product of the product family. (Chair.java, Sofa.java , CoffeeTable.java)

Step 2: Create Concrete Products of these interfaces (ModernChair.java, VictorainChair.java, ModernSofa.java , VictorianSofa.java, ModernCoffeeTable.java, VictorianCoffeeTable.java)

Step 3: Declare the Abstract Factory (FurnitureFactory.java)—an interface with a list of creation methods for all products that are part of a product family (createSofa(), createChair(), createCoffeeTable()). These method should return abstract product type.

Step 4: For each variant of a product family, we create a separate factory class from FurnitureFactory interface (VictorianFurnitureFactory.java, ModernFurnitureFactory.java)

Step 5: Create a factory creator class to get factories by passing an information such as design (FactoryCreator.java)

1.4 When is Abstract Factory Used?
  • The application needs to create multiple family of products
  • When you want to provide a library of objects that does not show implementations but only reveals interfaces.
Watch Abstract Factory Pattern on YouTube

Factory Method Design Pattern

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 ?

factory-method
Before Factory Method Pattern
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

factory-method
After Factory Method Design Pattern
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
Watch Factory Method Design Pattern on Youtube

Singleton Design Pattern

1.1 What is Singleton ?

Singleton basically means one. That is you can create only one instance of that class

1.2 How to Implement a Singleton?
  • The instance is stored as a private static variable(the instance is created when the variable is initialized, at some point before the static method is first called.
  • Declaring all constructors of the class to be private and
  • Providing a static method that returns a reference to that instance
1.3 Different Types of Implementation

Singleton design pattern can be implemented by two ways as mentioned below:

  1. Eager Instantiation
  2. Lazy Instantiation

Eager Instantiation: 

  • According to the principles of Eager Instantiation, the object should be created in advance and should be ready to use.
  • The very first line of this Singleton class that is private static Singleton instance = new Singleton();
  • Eager instantiation is thread safe. 

Lazy Instantiation: 

  • Lazy initialization of an object means that its creation is deferred until it is first used. Lazy initialization is primarily used to improve performance, avoid wasteful computation, and reduce program memory requirement.
  • The very first line of  this Singleton class that is : private static Singleton instance = null; 
  • Lazy instantiation is not  thread safe. 
Watch Singleton Design Pattern On YouTube
Eager Initialized Singleton Class Example
package com.coding.bee.dp.creational.singleton;
public class EagerSingletonAbc {
    private static EagerSingletonAbc instance = new EagerSingletonAbc();
    private EagerSingletonAbc() { }
    public static EagerSingletonAbc getInstance() {
		return instance;
	}
}
package com.coding.bee.dp.creational.singleton;
public class EagerSingletonDriver {

 public static void main(String[] args) {
     EagerSingletonAbc abc1 = EagerSingletonAbc.getInstance();
     EagerSingletonAbc abc2 = EagerSingletonAbc.getInstance();

     System.out.println(abc1.hashCode());
     System.out.println(abc2.hashCode());
   }
}

Lazy Initialized Singleton Class Example
package com.coding.bee.dp.creational.singleton;

public class LazySingletonAbc {
   private static LazySingletonAbc instance = null;
   private LazySingletonAbc() { }
   public static LazySingletonAbc getInstance() {
	if (instance == null) {
	   instance = new LazySingletonAbc();
	}
	   return instance;
	}
}

package com.coding.bee.dp.creational.singleton;
public class LazySingletonDriver {
	public static void main(String[] args) {
	   LazySingletonAbc abc1 = LazySingletonAbc.getInstance();
	   LazySingletonAbc abc2 = LazySingletonAbc.getInstance();

	   System.out.println(abc1.hashCode());
	   System.out.println(abc2.hashCode());
	}
}