The Abstract Factory Pattern in Java provides an interface for creating families of related or dependent objects without specifying their concrete classes.

For better understand of the pattern, take a look at my previous article about Factory Method Pattern 

Abstract Factory Pattern = Factory Method Pattern + Interfaces for creating families of related or dependent objects

Let’s look at fairly complicated class diagram for implementation with Factory Method Pattern in left side and interfaces for creating families of related dependent objects in right side and will see how it is connected to create pattern.

abstract factory pattern

High Level Steps for Implementation

  1. Create Abstract Product class 
  2. Create Concrete Product subclasses
  3. Create Abstract Creator class
  4. Create Concrete Creator subclasses
  5. Create Single Interface for factory methods
  6. Create Interface for every products in related family
  7. Create Concrete class for family of products implementing every product interface
  8. Run a test drive

Step 1: Create Abstract Product class

public abstract class Mobile {

  String name;

  Processor processor;
  RAM ram;
  Camera camera;
  MobileCase mobileCase;

  abstract void prepare();

  void assemble() {
    System.out.println("Assemble every parts");
  }

  void verify() {
    System.out.println("Verify mobile functions");
  }

  void boxIt() {
    System.out.println("Box it in respective Mobile box");
  }

  void setName(String name) {
    this.name = name;
  }

  String getName() {
    return name;
  }

  public String toString() {
    StringBuffer result = new StringBuffer();
    result.append("---- " + name + " ----\n");
    if (processor != null) {
      result.append(processor);
      result.append("\n");
    }
    if (ram != null) {
      result.append(ram);
      result.append("\n");
    }
    if (camera != null) {
      result.append(camera);
      result.append("\n");
    }
    
    if (mobileCase != null) {
      result.append(name+" "+mobileCase);
      result.append("\n");
    }
    return result.toString();
  }
}

Step 2: Create Concrete Product subclasses

public class OnePlus extends Mobile {
  MobilePartsFactory mobilePartsFactory;
  
  /**
   * MobilepartsFactory is passed in constructor to choose which
   * factory is choosed to prepare parts
  **/
  
  public OnePlus(MobilePartsFactory mobilePartsFactory) {
    this.mobilePartsFactory = mobilePartsFactory;
  }

  @Override
  void prepare() {
    System.out.println("Creating parts for "+this.name);
    processor = mobilePartsFactory.createProcessor();
    ram = mobilePartsFactory.createRam();
    camera = mobilePartsFactory.createCamera();
    mobileCase = mobilePartsFactory.createMobileCase();

  }

}
public class VivoMobile extends Mobile {
  MobilePartsFactory mobilePartsFactory;
  
  /**
   * MobilepartsFactory is passed in constructor to choose which
   * factory is choosed to prepare parts
  **/
  
  public VivoMobile(MobilePartsFactory mobilePartsFactory) {
    this.mobilePartsFactory = mobilePartsFactory;
  }

  @Override
  void prepare() {
    System.out.println("Creating parts for "+this.name);
    processor = mobilePartsFactory.createProcessor();
    ram = mobilePartsFactory.createRam();
    camera = mobilePartsFactory.createCamera();
    mobileCase = mobilePartsFactory.createMobileCase();

  }

}

Step 3: Create Abstract Creator class

public abstract class MobileStore {

  protected abstract Mobile createMobile(String type);
  
  public Mobile orderMobile(String type) {
    Mobile mobile = createMobile(type);
    System.out.println("--- Making a " + mobile.getName() + " ---");
    mobile.prepare();
    mobile.assemble();
    mobile.verify();
    mobile.boxIt();
    return mobile;
  }
}

Step 4: Create Concrete Creator subclasses

public class IndiaMobileStore extends MobileStore {

  @Override
  protected Mobile createMobile(String type) {
    Mobile mobile = null;
    MobilePartsFactory mobilePartsFactory = new IndiaMobilePartsFactory();
    
    if(type.equals("vivo")) {
      mobile = new VivoMobile(mobilePartsFactory);
      mobile.setName("India Vivo Model Phone");
    }
    else if(type.equals("oneplus")) {
      mobile = new OnePlus(mobilePartsFactory);
      mobile.setName("India OnePlus Model Phone");
    }
    
    return mobile;
  }

}

Similarly create USAMobileStore and so on..

Step 5: Create Single Interface for factory methods

public interface MobilePartsFactory {

  public Processor createProcessor();
  public RAM createRam();
  public Camera createCamera();
  public MobileCase createMobileCase();
}

Step 6: Create Interface for every products in related family

public interface Processor {
  
  public String toString();
}

public interface RAM {
  
  public String toString();
}
public interface Camera {
  
  public String toString();
}
public interface MobileCase {
  
  public String toString();
}

Step 7: Create Concrete class for family of products implementing every product interface

public class IndiaStandardCamera implements Camera {

  @Override
  public String toString() {
    return "India Standard Camera installed.";
  }
}
public class IndiaStandardProcessor implements Processor {

  @Override
  public String toString() {
    return "India Standard Processor Installed";
  }
}
public class IndiaStandardRAM implements RAM {
  @Override
  public String toString() {
    return "India Standard RAM installed";
  }
}
public class IndiaStandardMobileCase implements MobileCase {

  @Override
  public String toString() {
    return "MobileCase installed";
  }
}

Similarly create classes for USAStandardRAM, USAStandardCamera, and so on…

Step 8:

public class MobileTestDrive {
  public static void main(String[] args) {
    MobileStore indStore = new IndiaMobileStore();
    
    Mobile mobile = indStore.orderMobile("vivo");
    System.out.println("Making a order of "+ mobile);
    
    mobile = indStore.orderMobile("oneplus");
    System.out.println("Making a order of "+ mobile);
  }

}

Output

--- Making a India Vivo Model Phone ---
Creating parts for India Vivo Model Phone
Assemble every parts
Verify mobile functions
Box it in respective Mobile box
Making a order of ---- India Vivo Model Phone ----
India Standard Processor Installed
India Standard RAM installed
India Standard Camera installed.
India Vivo Model Phone MobileCase installed

--- Making a India OnePlus Model Phone ---
Creating parts for India OnePlus Model Phone
Assemble every parts
Verify mobile functions
Box it in respective Mobile box
Making a order of ---- India OnePlus Model Phone ----
India Standard Processor Installed
India Standard RAM installed
India Standard Camera installed.
India OnePlus Model Phone MobileCase installed

Abstract Factory allows a client to use an abstract interface to create a set of related products without knowing about the concrete products that are actually produced. In this way, the client is decoupled from any of the specifics of the concrete products.

Each factory produces a different implementation for the family of products.

All factory patterns promotes loose coupling by reducing the dependency of application on concrete classes.

Conclusion

Abstract Factory is used whenever we have families of products to create and make sure clients create family of products together.

Please follow and like us:
error