Coding With Fun
Home Docker Django Node.js Articles Python pip guide FAQ Policy

Abstract factory pattern


May 27, 2021 Design mode


Table of contents


Abstract factory pattern

Abstract Factory Pattern is the creation of other plants around one super-factory. T he super-factory is also known as the factory of other factories. This type of design pattern belongs to the creation pattern and provides the best way to create objects.

In abstract factory mode, interfaces are factories that are responsible for creating related objects and do not need to explicitly specify their classes. Each generated plant provides objects in accordance with the factory pattern.

Introduced

Intent: Provides an interface for creating a series of related or interdependent objects without specifying their specific classes.

Main solution: Mainly solve the problem of interface selection.

When to use: The system has more than one product family, and the system consumes only one of the products.

How to solve: Define multiple products in one product family.

Key code: Aggregate multiple similar products in one plant.

Application examples: work, in order to participate in some parties, there must be two or more sets of clothes, such as business clothes (sets, a series of specific products), fashion (sets, a series of specific products), and even for a family, there may be business women's wear, business men's wear, fashion women's wear, fashion men's wear, these are also sets, that is, a series of specific products. A ssuming a situation (which doesn't exist in reality, otherwise it's impossible to get into communism, but is conducive to explaining abstract factory patterns), in your home, a wardrobe (specific factory) can only store one of these clothes (sets, a series of specific products), and it's natural to take them out of this wardrobe every time you take them. Understand with OO's mind that all wardrobes (concrete factories) are wardrobes (abstract factories), and each set of clothes includes specific tops (a specific product), pants (a specific product), these specific tops are actually tops (abstract products), specific pants are pants (another abstract product).

Pros: When multiple objects in a product family are designed to work together, it ensures that clients always use only objects in the same product family.

Cons: Product family extension is very difficult to add a series of products, both in the abstract Creator code, but also in the specific code.

Use scene: 1, QQ for skin, a set of change together. 2 , the generation of different operating systems of the program.

Note: Product family is difficult to expand, product grade is easy to expand.

Realize

We'll create shape and Color interfaces and implement entity classes for those interfaces. T he next step is to create an abstract factory class, AbstractFactory. T he factory classes ShapeFactory and ColorFactory are then defined, both of which extend AbstractFactory. Then create a factory creator/generator class FactoryProducer.

AbstractFactoryPatternDemo, our demo class uses FactoryProducer to get the AbstractFactory object. I t passes shape information Shape (CIRCLE / RECTANGLE / SQUARE) to AbstractFactory to get the type of object it wants. It also passes color information Color (RED / GREEN / BLUE) to AbstractFactory to get the type of object it wants.

Abstract factory pattern

Step 1

Create an interface for the shape.

Shape.java

public interface Shape {
   void draw();
}

Step 2

Create an entity class that implements the interface.

Rectangle.java

public class Rectangle implements Shape {

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

Square.java

public class Square implements Shape {

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

Circle.java

public class Circle implements Shape {

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

Step 3

Create an interface for the color.

Color.java

public interface Color {
   void fill();
}

Step 4

Create an entity class that implements the interface.

Red.java

public class Red implements Color {

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

Green.java

public class Green implements Color {

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

Blue.java

public class Blue implements Color {

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

Step 5

Create abstract classes for Color and Shape objects to get the factory.

AbstractFactory.java

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

Step 6

Create a factory class that extends AbstractFactory to generate objects for entity classes based on given information.

ShapeFactory.java

public class ShapeFactory extends AbstractFactory {
    
   @Override
   public Shape getShape(String shapeType){
      if(shapeType == null){
         return null;
      }       
      if(shapeType.equalsIgnoreCase("CIRCLE")){
         return new Circle();
      } else if(shapeType.equalsIgnoreCase("RECTANGLE")){
         return new Rectangle();
      } else if(shapeType.equalsIgnoreCase("SQUARE")){
         return new Square();
      }
      return null;
   }
   
   @Override
   Color getColor(String color) {
      return null;
   }
}

ColorFactory.java

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("GREEN")){
         return new Green();
      } else if(color.equalsIgnoreCase("BLUE")){
         return new Blue();
      }
      return null;
   }
}

Step 7

Create a factory creator/generator class to get the factory by passing shape or color information.

FactoryProducer.java

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;
   }
}

Step 8

Use FactoryProducer to get AbstractFactory to get objects from entity classes by passing type information.

AbstractFactoryPatternDemo.java

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

      //获取形状工厂
      AbstractFactory shapeFactory = FactoryProducer.getFactory("SHAPE");

      //获取形状为 Circle 的对象
      Shape shape1 = shapeFactory.getShape("CIRCLE");

      //调用 Circle 的 draw 方法
      shape1.draw();

      //获取形状为 Rectangle 的对象
      Shape shape2 = shapeFactory.getShape("RECTANGLE");

      //调用 Rectangle 的 draw 方法
      shape2.draw();
      
      //获取形状为 Square 的对象
      Shape shape3 = shapeFactory.getShape("SQUARE");

      //调用 Square 的 draw 方法
      shape3.draw();

      //获取颜色工厂
      AbstractFactory colorFactory = FactoryProducer.getFactory("COLOR");

      //获取颜色为 Red 的对象
      Color color1 = colorFactory.getColor("RED");

      //调用 Red 的 fill 方法
      color1.fill();

      //获取颜色为 Green 的对象
      Color color2 = colorFactory.getColor("Green");

      //调用 Green 的 fill 方法
      color2.fill();

      //获取颜色为 Blue 的对象
      Color color3 = colorFactory.getColor("BLUE");

      //调用 Blue 的 fill 方法
      color3.fill();
   }
}

Step 9

Verify the output.

Inside Circle::draw() method.
Inside Rectangle::draw() method.
Inside Square::draw() method.
Inside Red::fill() method.
Inside Green::fill() method.
Inside Blue::fill() method.