Recent Posts

Sunday, 2 October 2016

Abstract Factory Design Pattern Tutorial


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;

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;

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;

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;

public interface MyComputerAbstractFactory {
 public MyComputer createComputer();
}
package com.ashok.designpatterns.abstractfactory;

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

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;

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;

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;

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

Next Tutorial  Prototype Design Pattern Tutorial

Previous Tutorial  Factory Design Pattern Tutorial

No comments:

Post a Comment