Abstract Factory Design Pattern

Abstract Factory Design Pattern

This is similar to Factory design pattern and it’s factory of factories. If you are familiar with factory design pattern in java, you will notice that we have a single Factory class that returns the different sub-classes based on the input provided and factory class uses if-else or switch statement to achieve this. Like factory design pattern, we will use the same super class and sub-classes.

Super class

Super class in factory design pattern can be an interface, abstract class or a normal java class. In our example, we have abstract super class with overridden toString() method for testing purpose.

package com.ashok.designpatterns.model;

/**
 * 
 * @author ashok.mariyala
 *
 */
public abstract class MyComputer {
   public abstract String getRAM();
   public abstract String getHDD();
   public abstract String getCPU();
   
   @Override
   public String toString(){
      return "RAM= "+this.getRAM()+", HDD="+this.getHDD()+", CPU="+this.getCPU();
   }
}
Sub class

Let’s say we have two sub classes MyPersonalComputer and Server with below implementation.

package com.ashok.designpatterns.model;

/**
 * 
 * @author ashok.mariyala
 *
 */
public class MyPersonalComputer extends MyComputer {
   private String ram;
   private String hdd;
   private String cpu;
   
   public MyPersonalComputer(String ram, String hdd, String cpu){
      this.ram = ram;
      this.hdd = hdd;
      this.cpu = cpu;
   }
   @Override
   public String getRAM() {
      return this.ram;
   }

   @Override
   public String getHDD() {
      return this.hdd;
   }

   @Override
   public String getCPU() {
      return this.cpu;
   }
}

Notice that both the classes are extending Computer super class.

package com.ashok.designpatterns.model;

/**
 * 
 * @author ashok.mariyala
 *
 */
public class MyServer extends MyComputer {

   private String ram;
   private String hdd;
   private String cpu;
   
   public MyServer(String ram, String hdd, String cpu){
      this.ram=ram;
      this.hdd=hdd;
      this.cpu=cpu;
   }
   @Override
   public String getRAM() {
      return this.ram;
   }

   @Override
   public String getHDD() {
      return this.hdd;
   }

   @Override
   public String getCPU() {
      return this.cpu;
   }
}

Now we need Factory Class for Each subclass. First of all we need to create a Abstract Factory interface or abstract class.

package com.ashok.designpatterns.abstractfactory;

import com.ashok.designpatterns.model.MyComputer;

/**
 * 
 * @author ashok.mariyala
 *
 */
public interface MyComputerAbstractFactory {
  public MyComputer createComputer();
}
package com.ashok.designpatterns.abstractfactory;

import com.ashok.designpatterns.model.MyComputer;
import com.ashok.designpatterns.model.MyPersonalComputer;

/**
 * 
 * @author ashok.mariyala
 *
 */
public class MyPersonalComputerFactory implements MyComputerAbstractFactory {

   private String ram;
   private String hdd;
   private String cpu;
   
   public MyPersonalComputerFactory(String ram, String hdd, String cpu){
      this.ram=ram;
      this.hdd=hdd;
      this.cpu=cpu;
   }
   @Override
   public MyComputer createComputer() {
      return new MyPersonalComputer(ram,hdd,cpu);
   }
}
package com.ashok.designpatterns.abstractfactory;

import com.ashok.designpatterns.model.MyComputer;
import com.ashok.designpatterns.model.MyServer;

/**
 * 
 * @author ashok.mariyala
 *
 */
public class MyServerFactory implements MyComputerAbstractFactory {

   private String ram;
   private String hdd;
   private String cpu;
   
   public MyServerFactory(String ram, String hdd, String cpu){
      this.ram=ram;
      this.hdd=hdd;
      this.cpu=cpu;
   }
   @Override
   public MyComputer createComputer() {
      return new MyServer(ram,hdd,cpu);
   }
}

Now we will create a consumer class that will provide the entry point for the client classes to create sub-classes.

package com.ashok.designpatterns.abstractfactory;

import com.ashok.designpatterns.model.MyComputer;

/**
 * 
 * @author ashok.mariyala
 *
 */
public class MyComputerFactory {
   public static MyComputer getComputer(MyComputerAbstractFactory factory){
      return factory.createComputer();
   }
}

Now, lets write a simple test method and see how to use the abstract factory to get the instance of sub-classes.

package com.ashok.designpatterns.test;

import com.ashok.designpatterns.abstractfactory.MyPersonalComputerFactory;
import com.ashok.designpatterns.abstractfactory.MyServerFactory;
import com.ashok.designpatterns.factory.MyComputerFactory;
import com.ashok.designpatterns.model.MyComputer;

/**
 * 
 * @author ashok.mariyala
 *
 */
public class MyTestDesignPatterns {
   public static void main(String[] args) {
      testAbstractFactory();
   }

   private static void testAbstractFactory() {
      MyComputer pc = com.ashok.designpatterns.abstractfactory.MyComputerFactory.getComputer(new MyPersonalComputerFactory("4 GB","500 GB","2.6 GHz"));
      MyComputer server = com.ashok.designpatterns.abstractfactory.MyComputerFactory.getComputer(new MyServerFactory("16 GB","1 TB","2.9 GHz"));
      System.out.println("AbstractFactory PC Configuration : "+pc);
      System.out.println("AbstractFactory Server Configuration : "+server);
   }
}

Output
AbstractFactory PC Configuration : RAM= 4 GB, HDD=500 GB, CPU=2.6 GHz
AbstractFactory Server Configuration : RAM= 16 GB, HDD=1 TB, CPU=2.9 GHz
Abstract Factory Design Pattern


Scroll to top