Sunday, July 12, 2015

Abstract Factory Design Pattern - GOF



Definition
https://en.wikipedia.org/wiki/Abstract_factory_pattern
The abstract factory pattern provides a way to encapsulate a group of individual factories that have a common theme without specifying their concrete classes.[1] In normal usage, the client software creates a concrete implementation of the abstract factory and then uses the generic interface of the factory to create the concrete objects that are part of the theme. The client doesn't know (or care) which concrete objects it gets from each of these internal factories, since it uses only the generic interfaces of their products.

An abstract factory is a factory that returns factories.
A normal factory can be used to create sets of related objects. 

UML Structures
Abstract factory UML.svg

AbstractFactory
This is an interface which is used to create abstract product
ConcreteFactory
This is a class which implements the AbstractFactory interface to create concrete products.
AbstractProduct
This is an interface which declares a type of product.
ConcreteProduct
This is a class which implements the AbstractProduct interface to create product.
Client
This is a class which use AbstractFactory and AbstractProduct interfaces to create a family of related objects.
https://dzone.com/articles/design-patterns-abstract-factory
The AbstractFactory defines the interface that all of the concrete factories will need to implement in order to product Products. 
ConcreteFactoryA and ConcreteFactoryB have both implemented this interface here, creating two seperate families of product. 
Meanwhile, AbstractProductA and AbstractProductB are interfaces for the different types of product. Each factory will create one of each of these AbstractProducts. 
The Client deals with AbstractFactoryAbstractProductA and AbstractProductB
It doesn't know anything about the implementations. The actual implementation ofAbstractFactory that the Client uses is determined at runtime.
Example
//Abstract Product
interface Button {
 void paint();
}
//Abstract Product
interface Label {
 void paint();
}

//Abstract Factory
interface GUIFactory {
 Button createButton();
 Label createLabel();
}

//Concrete Factory
class WinFactory implements GUIFactory {
 public Button createButton() {
  return new WinButton();
 }

 public Label createLabel() {
  return new WinLabel();
 }
}

//Concrete Factory
class OSXFactory implements GUIFactory {
 public Button createButton() {
  return new OSXButton();
 }

 public Label createLabel() {
  return new OSXLabel();
 }

}

//Concrete Product
class OSXButton implements Button {
 public void paint() {
  System.out.println("I'm an OSXButton");
 }
}

//Concrete Product
class WinButton implements Button {
 public void paint() {
  System.out.println("I'm a WinButton");
 }
}
Client:
 public Application(GUIFactory factory) { // factory = createOsSpecificFactory();
  Button button = factory.createButton();
  Label label = factory.createLabel();
  button.paint();
  label.paint();
 }
 public static GUIFactory createOsSpecificFactory() {
  String osname = System.getProperty("os.name").toLowerCase();
  if(osname != null && osname.contains("windows"))
   return new WinFactory();
  else
   return new OSXFactory();
 }
Factory Method Pattern vs. Abstract Factory Pattern
http://www.codeproject.com/Articles/716413/Factory-Method-Pattern-vs-Abstract-Factory-Pattern
//Client Code
IMachineFactory factory = new HighBudgetMachine();// Or new LowBudgetMachine();
ComputerShop shop = new ComputerShop(factory);
shop.AssembleMachine();  
public class ComputerShop
{
    IMachineFactory category;
    public ComputerShop(IMachineFactory _category)
    {
        category = _category;
    }
    public void AssembleMachine()
    {
        IProcessor processor = category.GetRam();
        IHardDisk hdd = category.GetHardDisk();
        IMonitor monitor = category.GetMonitor();
        //use all three and create machine

        processor.PerformOperation();
        hdd.StoreData();
        monitor.DisplayPicture();
    }
}

public interface IMachineFactory
{
    IProcessor GetRam();
    IHardDisk GetHardDisk();
    IMonitor GetMonitor();
}

public class HighBudgetMachine : IMachineFactory
{
    public IProcessor GetRam() { return new ExpensiveProcessor(); }
    public IHardDisk GetHardDisk() { return new ExpensiveHDD(); }
    public IMonitor GetMonitor() { return new HighResolutionMonitor(); }
}
public class LowBudgetMachine : IMachineFactory
{
    public IProcessor GetRam() { return new CheapProcessor(); }
    public IHardDisk GetHardDisk() { return new CheapHDD(); }
    public IMonitor GetMonitor() { return new LowResolutionMonitor(); }
}
//Let's say in future...Ram in the LowBudgetMachine is decided to upgrade then
//first make GetRam in LowBudgetMachine Virtual and create new class as follows

public class AverageBudgetMachine : LowBudgetMachine
{
    public override IProcessor GetRam()
    {
        return new ExpensiveProcessor();
    }
}
http://howtodoinjava.com/2012/10/29/abstract-factory-pattern-in-java/
Here the abstract factory returns concret product directly. -- not concret factory.
public class CarFactory
{
    private CarFactory() {
        //Prevent instantiation
    }
 
    public static Car buildCar(CarType type)
    {
        Car car = null;
        Location location = Location.ASIA; //Read location property somewhere from configuration
        //Use location specific car factory
        switch(location)
        {
            case USA:
            car = USACarFactory.buildCar(type);
            break;
            case ASIA:
            car = AsiaCarFactory.buildCar(type);
            break;
            default:
            car = DefaultCarFactory.buildCar(type);
        }
    return car;
    }
}
http://www.avajava.com/tutorials/lessons/abstract-factory-pattern.html
Is this good?

public class MammalFactory extends SpeciesFactory {

 @Override
 public Animal getAnimal(String type) {
  if ("dog".equals(type)) {
   return new Dog();
  } else {
   return new Cat();
  }
 }

}
SpeciesFactory speciesFactory1 = abstractFactory.getSpeciesFactory("reptile");
Animal a1 = speciesFactory1.getAnimal("tyrannosaurus")
Difference between Abstract Factory and Factory Method pattern:
http://idiotechie.com/abstract-factory-design-pattern-explained/
  • Factory Method pattern exposes a method to the client for creating the object whereas in case of Abstract Factory they expose a family of related objects which may consist of these Factory methods.
  • Factory Method pattern hides the construction of single object where as abstract factory method hides the construction of a family of related objects. Abstract factories are usually implemented using (a set of) factory methods.
In JDK
XML API implements abstract factory. There is a class name SchemaFactory. This acts as a factory and supports implemenation of multiple schemas using abstract factory design pattern.
DocumentBuilderFactory#newInstance()
TransformerFactory#newInstance()

http://www.codeproject.com/Articles/185349/Abstract-Factory-Design-Pattern



Labels

Review (572) System Design (334) System Design - Review (198) Java (189) Coding (75) Interview-System Design (65) Interview (63) Book Notes (59) Coding - Review (59) to-do (45) Linux (43) Knowledge (39) Interview-Java (35) Knowledge - Review (32) Database (31) Design Patterns (31) Big Data (29) Product Architecture (28) MultiThread (27) Soft Skills (27) Concurrency (26) Cracking Code Interview (26) Miscs (25) Distributed (24) OOD Design (24) Google (23) Career (22) Interview - Review (21) Java - Code (21) Operating System (21) Interview Q&A (20) System Design - Practice (20) Tips (19) Algorithm (17) Company - Facebook (17) Security (17) How to Ace Interview (16) Brain Teaser (14) Linux - Shell (14) Redis (14) Testing (14) Tools (14) Code Quality (13) Search (13) Spark (13) Spring (13) Company - LinkedIn (12) How to (12) Interview-Database (12) Interview-Operating System (12) Solr (12) Architecture Principles (11) Resource (10) Amazon (9) Cache (9) Git (9) Interview - MultiThread (9) Scalability (9) Trouble Shooting (9) Web Dev (9) Architecture Model (8) Better Programmer (8) Cassandra (8) Company - Uber (8) Java67 (8) Math (8) OO Design principles (8) SOLID (8) Design (7) Interview Corner (7) JVM (7) Java Basics (7) Kafka (7) Mac (7) Machine Learning (7) NoSQL (7) C++ (6) Chrome (6) File System (6) Highscalability (6) How to Better (6) Network (6) Restful (6) CareerCup (5) Code Review (5) Hash (5) How to Interview (5) JDK Source Code (5) JavaScript (5) Leetcode (5) Must Known (5) Python (5)

Popular Posts