Design Mode - Factory Mode

1. Factory Method

Define an interface for creating objects so that subclasses decide which class to instantiate. Factory Method delays the instantiation of a class to its subclasses.

The purpose of the factory method is to separate the creation and use of objects, and clients always reference Abstract factories and abstract products:

┌─────────────┐      ┌─────────────┐
│   Product   │      │   Factory   │
└─────────────┘      └─────────────┘
       ▲                    ▲
       │                    │
┌─────────────┐      ┌─────────────┐
│ ProductImpl │<─ ─ ─│ FactoryImpl │
└─────────────┘      └─────────────┘

Factory Interface:

public interface NumberFactory {
    Number parse(String s);
}

Factory implementation class:

public class NumberFactoryImpl implements NumberFactory {
    public Number parse(String s) {
        return new BigDecimal(s);
    }
}

The product interface is Number, and the actual product returned by NumberFactoryImpl is BigDecimal

How do clients create NumberFactoryImpl? Typically, we define a static method getFactory() in the Interface Factory to return the true subclass:

public interface NumberFactory {
    // Create method:
    Number parse(String s);
    // Get a factory instance:
    static NumberFactory getFactory() {
        return impl;
    }
    //Get Implementation Class
    static NumberFactory impl = new NumberFactoryImpl();
}

On the client side, we only need to deal with the factory interface NumberFactory and the abstract product Number:

NumberFactory factory = NumberFactory.getFactory();
Number result = factory.parse("123.456");

The caller can completely ignore the true factory NumberFactoryImpl and the actual product BigDecimal, which has the advantage of allowing the code that creates the product to transform independently without affecting the caller.

2. Static Factory Method.

Static factory methods are widely used in Java Standard Libraries

Integer n = Integer.valueOf(100);
#Integer n = new Integer(100);

Integer is both a product and a static factory. It provides a static method, valueOf(), to create Integer. So what's the difference between this and writing new Integer(100)? Let's look at the valueOf() method:

public final class Integer {
    public static Integer valueOf(int i) {
        if (i >= IntegerCache.low && i <= IntegerCache.high)
            return IntegerCache.cache[i + (-IntegerCache.low)];
        return new Integer(i);
    }
    ...
}

valueOf() may use new internally to create a new Integer instance, but it may also return a cached Integer instance directly. It is not necessary for the caller to know the details of Integer creation.

If the caller uses Integer n = new Integer(100) directly, it loses the possibility of using cache optimization.

The factory method hides the details of creating the product, and does not necessarily create the product every time. Instead, it can return the cached product, increasing speed and reducing memory consumption.

3. Abstract Factory Method

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

The abstract factory model is different from the factory method. It solves complex problems. Not only is the factory abstract, the product abstract, but there are many products to be created. Therefore, this abstract factory corresponds to many actual factories, each of which is responsible for creating many actual products:

                                ┌────────┐
                             ─ >│ProductA│
┌────────┐    ┌─────────┐   │   └────────┘
│ Client │─ ─>│ Factory │─ ─
└────────┘    └─────────┘   │   ┌────────┐
                   ▲         ─ >│ProductB│
           ┌───────┴───────┐    └────────┘
           │               │
      ┌─────────┐     ┌─────────┐
      │Factory1 │     │Factory2 │
      └─────────┘     └─────────┘
           │   ┌─────────┐ │   ┌─────────┐
            ─ >│ProductA1│  ─ >│ProductA2│
           │   └─────────┘ │   └─────────┘
               ┌─────────┐     ┌─────────┐
           └ ─>│ProductB1│ └ ─>│ProductB2│
               └─────────┘     └─────────┘

Keywords: Java

Added by andreiga on Sun, 17 Oct 2021 19:11:59 +0300