Simple factory

define

Defines an interface for creating objects, but it is up to subclasses to decide which class to instantiate. The factory method lets classes defer instantiation to subclasses.

Interface oriented programming can isolate a host of possible changes to the system. Through polymorphism, it can implement the interface with any new class.

The class diagram

code

public class Client {
    public static void main(String[] args){}// Abstract product
    public interface Product {
        void show();
    }

    // Specific product: ProductA
    static class ConcreteProduct1 implements Product {
        public void show() {
            System.out.println("Specific product 1 shows..."); }}// Specific product: ProductB
    static class ConcreteProduct2 implements Product {
        public void show() {
            System.out.println("Specific product 2 shows...");
        }
    }

    final class Const {
        static final int PRODUCT_A = 0;
        static final int PRODUCT_B = 1;
        static final int PRODUCT_C = 2;
    }

    static class SimpleFactory {
        public static Product makeProduct(int kind) {
            switch (kind) {
                case Const.PRODUCT_A:
                    return new ConcreteProduct1();
                case Const.PRODUCT_B:
                    return new ConcreteProduct2();
            }
            return null; }}}Copy the code

Advantages:

  1. The factory class contains the logical judgment necessary to determine which instance of a product to create and when. The client can be relieved of the responsibility of creating product objects directly, making it easy to create corresponding products. The responsibilities of plant and product are clearly differentiated.
  2. The client does not need to know the class name of the specific product being created, just the parameters.
  3. Configuration files can also be introduced to replace and add new concrete product classes without modifying the client code.

Disadvantages:

  1. The simple factory mode has a single factory class, which is responsible for the creation of all products. The responsibility is too heavy. Once an exception occurs, the whole system will be affected. And the factory class code will be very bloated, against the principle of high aggregation.
  2. Using the simple factory pattern increases the number of classes in the system (introducing new factory classes), increasing the complexity and difficulty of understanding the system
  3. It is difficult to expand the system. Once a new product is added, the factory logic has to be modified. The logic may be too complicated when there are many product types
  4. The simple factory pattern uses the static factory approach, which prevents the factory roles from forming an inheritance-based hierarchy.

The problem

Q: What is the difference between defining a factory as a static method and a non-static method?

A: Static method advantage: you do not need to instantiate the object. Disadvantages: You cannot change the behavior of creating methods through inheritance.

The factory method

The class diagram

code

package FactoryMethod;

public class AbstractFactoryTest {
    public static void main(String[] args) {
        try {
            Product a;
            AbstractFactory af;
            af = (AbstractFactory) FractoryCreate.getFractoryInstance("package.ConcreteFactory1");
            a = af.newProduct();
            a.show();
        } catch(Exception e) { System.out.println(e.getMessage()); }}}// Abstract product: Provides an interface to the product
interface Product {
    public void show();
}

Concrete product 1: Implements abstract methods in abstract products
class ConcreteProduct1 implements Product {
    public void show() {
        System.out.println("Specific product 1 shows..."); }}Concrete product 2: Implements abstract methods in abstract products
class ConcreteProduct2 implements Product {
    public void show() {
        System.out.println("Specific product 2 shows..."); }}// Abstract factory: provides a method to generate factory goods
interface AbstractFactory {
    public Product newProduct();
}

// Factory 1: implementation of factory product generation method
class ConcreteFactory1 implements AbstractFactory {
    public Product newProduct() {
        System.out.println("Specific plant 1 generates --> Specific product 1...");
        return newConcreteProduct1(); }}// Factory 2: implementation of factory product generation method
class ConcreteFactory2 implements AbstractFactory {
    public Product newProduct() {
        System.out.println("Specific factory 2 generated --> Specific product 2...");
        return new ConcreteProduct2();
    }
}


public class FractoryCreate {
    public static AbstractFactory getFractoryInstance(String className) {
        Class clz = null;

        try{ clz = Class.forName(className); Constructor<? > []constructors = clz.getConstructors();

            return (Login) constructors[0].newInstance(context);
        } catch (Exception e) {
            e.printStackTrace();

            if (e instanceof ClassNotFoundException) {
                throw new RuntimeException(String.format("Can't find class(%s)", className));
            } else {
                throw new RuntimeException(String.format("Can't invoke newInstance for class(%s)", className)); }}}}Copy the code

Advantages:

  1. Users only need to know the name of the specific factory to get the product they want, without knowing the specific creation process of the product.
  2. Increased flexibility, for the creation of new products, only need to write a corresponding factory class.
  3. A typical decoupling framework. A high-level module only needs to know the abstract class of the product and does not need to care about other implementation classes, satisfying Demeter’s law, dependency inversion principle and Richter’s substitution principle.

Disadvantages:

  1. It is easy to have too many classes and add complexity
  2. The system is abstract and difficult to understand
  3. Abstract products can only produce one product, which can be solved by using the abstract factory model.

Reference:

  • Head First design pattern
  • Simple Factory model