Wednesday, June 1, 2022

Degin Pattern: Abstract Factory Pattern

Chapters

Abstract Factory Pattern

Abstract factory pattern is just like factory pattern, but this pattern deals with a family of objects and its variants. For example, we are creating classes for two GUI component providers. Both create GUI components but they have different design.

We can use abstract factory method to create a class design in this scenario. Take a look at this example.
/*
Client
*/
import factories;

public class ClientCode{

  public static void main(String[] args){
    GUIComponentsFactory factory = 
    GUIComponentsFactory.
    selectFactory("Unix");
    Button createdButton = null;
    RadioButton createdRadioButton = null;
    
    if(factory != null){
      createdButton = 
      factory.createButton("MyButton");
      System.out.println
      ("Created Button: " + 
       createdButton.getName());
      System.out.println();
      
      createdRadioButton = 
      factory.createRadioButton("MyRadioButton");
      System.out.println
      ("Created Button: " + 
       createdRadioButton.getName());
    }
  }
}

/*
Factories
Assume classes below are part of factories package
*/

public interface GUIComponentsFactory{
  
  Button createButton(String name);
  RadioButton createRadioButton(String name);
  
  public static GUIComponentsFactory selectFactory(String provider){
    GUIComponentsFactory factory = null;
    
    switch(provider){
    
      case "Windows":
      factory = new CreateWinComponents();
      break;
      
      case "Unix":
      factory = new CreateUnixComponents();
      break;
    }
    return factory;
  }
}

class CreateWinComponents implements GUIComponentsFactory{
  
  CreateWinComponents(){}
  
  @Override
  public Button createButton(String name){
    return new WinButton(name);
  }
  
  @Override
  public RadioButton createRadioButton(String name){
    return new WinRadio(name);
  }
  
}

class CreateUnixComponents implements GUIComponentsFactory{
  
  CreateUnixComponents(){}
  
  @Override
  public Button createButton(String name){
    return new UnixButton(name);
  }
  
  @Override
  public RadioButton createRadioButton(String name){
    return new UnixRadio(name);
  }
}

/*
Objects
*/

pubic abstract class Button{
  private String name;
  
  Button(String name){
    this.name = name;
  }
  
  public String getName(){
    return name;
  }
  
}

class WinButton extends Button{

  WinButton(String name){
    super(name);
    System.out.println(name + 
    " Windows Button has been created!");
  }
}

class UnixButton extends Button{

  UnixButton(String name){
    super(name);
    System.out.println(name + 
    " Unix Button has been created!");
  }
}

public abstract class RadioButton{
  private String name;
  
  RadioButton(String name){
    this.name = name;
  }
  
  public String getName(){
    return name;
  }
  
}

class WinRadio extends RadioButton{

  WinRadio(String name){
    super(name);
    System.out.println(name + 
    " Windows Radio Button has been created!");
  }
}

class UnixRadio extends RadioButton{

  UnixRadio(String name){
    super(name);
    System.out.println(name + 
    " Unix Radio Button has been created!");
  }
}

Result
MyButton Unix Button has been created!
Created Button: MyButton

MyRadioButton Unix Radio Button has been created!
Created Button: MyRadioButton
Just like in factory pattern, factory superclass and objects superclass should be non-instantiable. In short, they can't be instantiated.

One of the advantages of abstract factory pattern over factory pattern is that this pattern implements greater abstraction than factory pattern. However, if you're not producing a family of objects, it's better to use factory pattern.

This pattern inherits the advantages and disadvantages of factory pattern. For more information, you may visit this website

No comments:

Post a Comment