Home > Java > javaTutorial > Detailed explanation of abstract factory in Java

Detailed explanation of abstract factory in Java

黄舟
Release: 2017-09-15 09:51:50
Original
1206 people have browsed it

This article mainly introduces the relevant information of the abstract factory of Java design pattern in detail, which has certain reference value. Interested friends can refer to it

1. Concept

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

2. Pattern motivation

This series of objects are interdependent and equivalent to a product family

3. The structure of the pattern

We can clearly see from the above figure that the abstract factory pattern includes the following 4 roles:

 1. Abstract Factory role (AbstractFactory): The core of the abstract factory pattern, which has nothing to do with specific business logic. It is usually a JAVA interface or abstract class.

 2. Concrete Factory role: This role is usually closely related to specific business logic. The factory method in this role instantiates specific products and returns them based on specific business logic. The client uses this Role and call the factory method of the role to obtain a specific product object. This role is usually assumed by a specific JAVA class.

 3. Abstract product role: The class that plays this role is the parent class of the product created by the factory method pattern, or the interface they share, usually an interface or abstract class.

4. Specific product role: Any product created by the abstract factory pattern is an instance of this role, and has a specific JAVA class to assume it.

The sample code is as follows:


public class AbstractProductA 
{
  
  /**
  * @roseuid 59AC05990327
  */
  public AbstractProductA() 
  {
  
  }
}


public class ProductA1 extends AbstractProductA 
{
  
  /**
  * @roseuid 59AC05990359
  */
  public ProductA1() 
  {
  
  }
}


public class ProductA2 extends AbstractProductA 
{
  
  /**
  * @roseuid 59AC05990381
  */
  public ProductA2() 
  {
  
  }
}

public class AbstractProductB 
{
  
  /**
  * @roseuid 59AC059903BA
  */
  public AbstractProductB() 
  {
  
  }
}

public class ProductB1 extends AbstractProductB 
{
  
  /**
  * @roseuid 59AC059A001F
  */
  public ProductB1() 
  {
  
  }
}

public class ProductB2 extends AbstractProductB 
{
  
  /**
  * @roseuid 59AC059A0049
  */
  public ProductB2() 
  {
  
  }
}


public abstract class AbstractFactory 
{
  
  /**
  * @roseuid 59AC05690005
  */
  public AbstractFactory() 
  {
  
  }
  
  /**
  * @return AbstractProductA
  * @roseuid 59ABFB0103BE
  */
  public Abstract AbstractProductA createProductA() ;
  
  
  /**
  * @return AbstractProductB
  * @roseuid 59ABFB3B029D
  */
  public Abstract AbstractProductB createProductB() ;
}


public class ConcreteFactory1 extends AbstractFactory 
{
  
  /**
  * @roseuid 59AC057A02FC
  */
  public ConcreteFactory1() 
  {
  
  }
  
  /**
  * @return AbstractProductA
  * @roseuid 59ABFB9C00C9
  */
  public AbstractProductA createProductA() 
  {
    return new ProductA1();
  }
  
  /**
  * @return AbstractProductB
  * @roseuid 59ABFBA30011
  */
  public AbstractProductB createProductB() 
  {
    return new ProductB1();
  }
}



public class ConcreteFactory2 extends AbstractFactory 
{
  
  /**
  * @roseuid 59AC057A02C0
  */
  public ConcreteFactory2() 
  {
  
  }
  
  /**
  * @return AbstractProductA
  * @roseuid 59ABFCC701B9
  */
  public AbstractProductA createProductA() 
  {
    return new ProductA2();
  }
  
  /**
  * @return AbstractProductB
  * @roseuid 59ABFCC9001F
  */
  public AbstractProductB createProductB() 
  {
    return new ProductB2();
  }
}
Copy after login


public class Client 
{
  
  
  /**
  * @roseuid 59AC055700AB
  */
  public Client() 
  {
  
  }

  public static void main(String[] args){
      AbstractFactory theAbstractFactory;
    AbstractProductA theAbstractProductA;
    AbstractProductB theAbstractProductB;

    theAbstractFactory=new ConcreteFactory1();

    theAbstractProductA=theAbstractFactory.createProductA();
    theAbstractProductB=theAbstractFactory.createProductB();
 
  }
}
Copy after login

According to the above pattern structure diagram, we provide a creation A series of interfaces for related or interdependent objects without specifying their specific classes." A brief analysis:

1. Related or interdependent objects, here are instances of ProductA1 and instances of ProductB1 It is a set of interrelated (such as internal relationships) or interdependent (such as whole and part) relationships. According to business logic, ProductA1

can only be related to ProductB1 under the same product hierarchy structure AbstractProductB but cannot be related to ProductB2 is associated together.

 2. Provide an interface for creating a series of related or interdependent objects without specifying their specific classes. The interfaces here are AbstractProductA and AbstractProductB in the structure diagram. The client only relies on these. The interface of the product is programmed without relying on the specific implementation, which complies with the dependency inversion principle. "There is no need to specify their specific classes" That is, the client does not know the existence of ProductA1, ProductA2, ProductB1 and ProductB2. The client only needs to call the factory method of the specific factory to return the specific product instance.

4. Pattern Example

We will follow the example in the factory method pattern for further analysis. Now this tire factory is no longer satisfied with only producing car tires. , he has now introduced the engine production line (EngineLine), door (DoorLine) and other various parts production lines for the entire car. It can be said that he can now easily manufacture a Car, but not all Cars can be manufactured. For example, he Currently, it can only produce two types of cars: Benz and BMW (such a factory is enough for NX). For example, a car now only contains tires, doors and engines (of course there must be more than that), then this factory can follow the BMW and Benz cars have been produced according to the customer's requirements, as shown below:

The code is as follows:


public interface Door {
  public void open();
  public void close();
}
public class BenzDoor implements Door {

  @Override
  public void open() {
    System.out.println("奔驰车门开");
  }

  @Override
  public void close() {
    System.out.println("奔驰车门关");
  }
}
public class BmwDoor implements Door {

  @Override
  public void open() {
    System.out.println("宝马车门开");
  }

  @Override
  public void close() {
    System.out.println("宝马车门关");
  }

}
public interface Tire {
  public void getColor();
  public void getLife();
  public void getWidth();
}
public class BenzTire implements Tire {

  @Override
  public void getColor() {
    System.out.println("benz车color");
  }

  @Override
  public void getLife() {
    System.out.println("benz车life");
  }

  @Override
  public void getWidth() {
    System.out.println("benz车width");
  }
}
public class BmwTire implements Tire {

  @Override
  public void getColor() {
    System.out.println("bmw车color");
  }

  @Override
  public void getLife() {
    System.out.println("bmw车life");
  }

  @Override
  public void getWidth() {
    System.out.println("bmw车width");
  }

}
public interface Engine {
  public void start();

  public void stop();

}
public class BenzEngine implements Engine {

  @Override
  public void start() {
    System.out.println("benz车start");

  }

  @Override
  public void stop() {
    System.out.println("benz车stop");

  }

}
public class BmwEngine implements Engine {

  @Override
  public void start() {
    System.out.println("bmw车start");

  }

  @Override
  public void stop() {
    System.out.println("bmw车stop");

  }

}
public interface PartFactory {
  public Door createDoor();

  public Tire createTire();

  public Engine createEngine();

}
public class BenzPartFactory implements PartFactory {

  @Override
  public Door createDoor() {
    return new BenzDoor();
  }

  @Override
  public Tire createTire() {
    return new BenzTire();
  }

  @Override
  public Engine createEngine() {
    return new BenzEngine();
  }

}
public class BmwPartFactory implements PartFactory {

  @Override
  public Door createDoor() {
    return new BmwDoor();
  }

  @Override
  public Tire createTire() {
    return new BmwTire();
  }

  @Override
  public Engine createEngine() {
    return new BmwEngine();
  }

}
public class Car {
  private Door door;
  private Engine engine;
  private Tire tire;

  public Car(PartFactory factory) {
    this.door = factory.createDoor();
    this.engine = factory.createEngine();
    this.tire = factory.createTire();
  }

  public Door getDoor() {
    return door;
  }

  public Engine getEngine() {
    return engine;
  }

  public Tire getTire() {
    return tire;
  }  
}
public class Client {
  
  public static void main(String[] args) {
    PartFactory partFactory=new BenzPartFactory();
    Car benzCar=new Car(partFactory);
    
    benzCar.getDoor().open();
    benzCar.getEngine().start();
    benzCar.getTire().getColor();
    
  }

}
Copy after login

The running results are as follows :

Benz car door open
Benz car start
Benz car color

According to the above class diagram and operation results, the following analysis can be done:

BenzDoor, BenzTire and BenzEngine have a strong relationship. We can say that a Benz car cannot use Bmw doors, that is, BmwDoor. This strong relationship is well maintained through BenzPartFactory. For the client, like the client class above, if the customer wants a benz car, then I only need a factory that produces benz cars. All product instances in this factory are parts of benz cars. We can also see from the running results.

Imagine that with the development of this factory, it will now also produce Audi cars. At this time, we only need to add an Audi door class AudiDoor, AudiTire, AudiEngine and AudiPartFactory. Other classes do not need to be added. any modifications. But the customer said that I want to install a pair of wings on the car so that it can fly when there is a traffic jam. At this time, we have to add a factory method that can return the wings to each factory and make modifications to each factory. This is inconsistent with Open and closed principle. Therefore, the abstract factory does not support the open-close principle for adding product hierarchical structures, but supports the open-close principle for product family dimensions (such as Audi cars).

5. Mode Constraints

It is suitable for generating an interrelated or dependent product family, and supports expansion in the product family direction, but is not suitable for product level direction. extension.

6. Pattern Variations and Extensions

1. Abstract factory provides static factory method: Abstract factory can provide a static factory method, which is returned through parameters Concrete factory instance.

 2. Merge the abstract factory with the specific factory: If it is determined that there is only one product family in the direction of product family, then the abstract factory is not necessary. At this time, only one specific factory is needed. We can Going further, provide a static method for this specific factory, which returns its own instance.

7. Relationship with other patterns

If there is only one product level structure, then it is the factory method pattern, as shown below:

If there are multiple product hierarchical structures, then each factory method in the abstract factory is a "factory method" pattern.

8. Advantages and Disadvantages of the Model

The open-close principle is supported in the direction of the product family, but the open-close principle is not supported in the direction of the product hierarchy.

The above is the detailed content of Detailed explanation of abstract factory in Java. For more information, please follow other related articles on the PHP Chinese website!

Related labels:
source:php.cn
Statement of this Website
The content of this article is voluntarily contributed by netizens, and the copyright belongs to the original author. This site does not assume corresponding legal responsibility. If you find any content suspected of plagiarism or infringement, please contact admin@php.cn
Popular Tutorials
More>
Latest Downloads
More>
Web Effects
Website Source Code
Website Materials
Front End Template