Abstract Factory Pattern Explanation

僤鯓⒐⒋嵵緔 提交于 2019-12-11 01:56:28

问题


I was studying the design patterns and came across Abstract Factory Pattern which by definition is :

Abstract Factory Pattern says that just define an interface or abstract class for creating families of related (or dependent) objects but without specifying their concrete sub-classes.That means Abstract Factory lets a class returns a factory of classes.

But I am not able to understand it thoroughly. I even went through some examples given in this link and this question, but nothing helped.

Can anyone provide a clear explanation with a simple, real life example of Abstract Factory Pattern and the cases in which we should use this design pattern.


回答1:


This is the flow of the Abstract factory pattern.Its implemented in java

//create a shape interface and implementer classes shape

public interface Shape {
   void draw();
}

public class Rectangle implements Shape {

   @Override
   public void draw() {
      System.out.println("Inside Rectangle::draw() method.");
   }
}

public class Square implements Shape {

   @Override
   public void draw() {
      System.out.println("Inside Square::draw() method.");
   }
}

//create color interface and its implementers

public interface Color {
   void fill();
}

public class Red implements Color {

   @Override
   public void fill() {
      System.out.println("Inside Red::fill() method.");
   }
}


public class Blue implements Color {

   @Override
   public void fill() {
      System.out.println("Inside Blue::fill() method.");
   }
}

//create abstract factory class that is generally a class that generates the interfaces or in easy language a factory that can manufacture anything you ask of it

public abstract class AbstractFactory {
   abstract Color getColor(String color);
   abstract Shape getShape(String shape) ;
}

//create shape factory just like you know normal factories manufacture things. This is the factory that manufactures shapes.you just give it the name of the shape you want and it will manufacture it

public class ShapeFactory extends AbstractFactory {

   @Override
   public Shape getShape(String shapeType){

      if(shapeType == null){
         return null;
      }     

      if(shapeType.equalsIgnoreCase("RECTANGLE")){
         return new Rectangle();

      }else if(shapeType.equalsIgnoreCase("SQUARE")){
         return new Square();
      }

      return null;
   }

   @Override
   Color getColor(String color) {
      return null;
   }
}

//color factory .This is the factory that manufactures colors . you just give it the name of the color you want and it will manufacture it

public class ColorFactory extends AbstractFactory {

   @Override
   public Shape getShape(String shapeType){
      return null;
   }

   @Override
   Color getColor(String color) {

      if(color == null){
         return null;
      }     

      if(color.equalsIgnoreCase("RED")){
         return new Red();

      }else if(color.equalsIgnoreCase("BLUE")){
         return new Blue();
      }

      return null;
   }
}

//produces factories .Now this class is like an investor who constructs factories . give it the name and it will construct for you the factory that manufactures that.

public class FactoryProducer {
   public static AbstractFactory getFactory(String choice){

      if(choice.equalsIgnoreCase("SHAPE")){
         return new ShapeFactory();

      }else if(choice.equalsIgnoreCase("COLOR")){
         return new ColorFactory();
      }

      return null;
   }
}

//This is the demo class like the dealer who would request an investor to construct a shape factory and this factory can then manufacture rectangles, squares etc.

public class AbstractFactoryPatternDemo {
   public static void main(String[] args) {

      //get shape factory
      AbstractFactory shapeFactory = FactoryProducer.getFactory("SHAPE");


      //get an object of Shape Rectangle
      Shape shape2 = shapeFactory.getShape("RECTANGLE");

      //call draw method of Shape Rectangle
      shape2.draw();

      //get an object of Shape Square 
      Shape shape3 = shapeFactory.getShape("SQUARE");

      //call draw method of Shape Square
      shape3.draw();

      //get color factory
      AbstractFactory colorFactory = FactoryProducer.getFactory("COLOR");

      //get an object of Color Red
      Color color1 = colorFactory.getColor("RED");

      //call fill method of Red
      color1.fill();


      //get an object of Color Blue
      Color color3 = colorFactory.getColor("BLUE");

      //call fill method of Color Blue
      color3.fill();
   }
}



回答2:


The key word for abstract factory is the "families". Below is my very simple example.

As you can see, the Boss does not need to know what kind of factory it is, as long as it is a VehichleFacotry. Boss simply invokes Build() and the relative Vehicle is created.

abstract class Vehicle { }

class Car : Vehicle { }

class Bus : Vehicle { }

abstract class VehicleFactory 
{
    abstract Vehicle Build();    
}

class CarVehicleFactory : VehicleFacory
{
    Vehicle Build()
    {
        return new Car();
    }
}

class BusVehicleFactory : VehicleFacory
{
    Vehicle Build()
    {
        return new Bus();
    }
}

public class Boss
{
    public void Order(VehicleFactory factory)
    {
        var vehicle = factory.Build();
        //do something else ...
    }
}

public class Foo
{
    public void Bar()
    {
        var boss = new Boss();

        boss.Order(new CarVehicleFactory());
        boss.Order(new BusVehicleFactory());
    }
}



回答3:


Suppose you are designing a page in which you need to fetch the data from the server(with paging), trigger some analytics events and has customisable views.

Now you want this page to be generic enough to be used by anyone who wishes to use same set of functionalities.

So what could differ?

  1. the Endpoint from where you fetch the data.

  2. Analytics you want to trigger for various events (when user scrolls some views, click on some view, on page load, when user navigates to next page etc)

  3. Different Menu items for different pages.

You can encapsulate what varies and put them into separate classes. Something like this

class MyPage {
  IDataFetcher datafetcher;
  IAnalyticsHelper analyticsHelper;
  IMenuBuilder menuBuilder;
}

Now your MyPage class depends on these classes for the page to be rendered. But if you observe closely these are the family of algorithms which will work together in order to render a page. (A big hint that you could use an abstract factory).

So probably you could change your code to :

public interface IPageAbstractFactory {
      IDataFetcher getDatafetcher();
      IAnalyticsHelper getAnalyticsHelper();
      IMenuBuilder getMenuBuilder();
}

class MyPage {
      IPageFactory factory;
    }

We just implemented an abstract factory!!! I hope my example is clear.



来源:https://stackoverflow.com/questions/38504837/abstract-factory-pattern-explanation

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!