Design pattern - creation pattern - factory pattern (simple factory, factory method, abstract factory)

Factory Pattern provides the best way to create objects. We don't have to care about the creation details of objects, we just need to obtain different products according to different situations

1. Factory simple mode

In the simple factory pattern, the method used to create instances is usually static, also known as static factory pattern. It does not belong to 23 design patterns, but it is often used in reality.

  • Abstract class or interface: it defines the specification of the Product and describes the main characteristics and functions of the Product. For example, in the example, the Product definition obtains automobile products
  • Concrete implementation: it implements the interface defined by the abstract Product role. For example, in the example, the implementation class of Product is mainly responsible for producing specific cars
  • Factory: a static factory method is provided in the factory class, which is responsible for creating instances of all specific product classes. The factory class can be directly called by the outside world to create the required product object. SimpleFactory produces the required products according to the type

public class SimpleFactoryDemo {

    public static void main(String[] args) {
        // Get products
        Product benz = SimpleFactory.getProduct("benz");
        // Call product method
        benz.getProduct();
        Product bmw = SimpleFactory.getProduct("bmw");
        bmw.getProduct();
        Product audi = SimpleFactory.getProduct("audi");
        audi.getProduct();


    }

}

/**
 * Define the interface of a product
 *    Method principle defined in design interface: it will not change due to product change
 * @author liushiwei
 */
interface Product{
    /**
     * Get products
     */
    public void getProduct();

}

/**
 * Benz
 */
class Benz implements Product{

    @Override
    public void getProduct() {
        System.out.println("Mercedes Benz");
    }
}

/**
 * bmw
 */
class Bmw implements Product{

    @Override
    public void getProduct() {
        System.out.println("BMW");
    }
}

/**
 * audi
 */
class Audi implements Product{

    @Override
    public void getProduct() {
        System.out.println("Audi");
    }
}

/**
 * Factory, responsible for the production of required products
 */
class SimpleFactory{

    public static Product getProduct(String type){
        if(StringUtils.isEmpty(type)){
            return null;
        }else{
            if("audi".equals(type)){
                return new Audi();
            }else if("bmw".equals(type)){
                return new Bmw();
            }else if("benz".equals(type)){
                return new Benz();
            }else{
                return null;
            }
        }
    }
}
  • Advantages: the simple factory pattern can decide which specific class object should be created according to the information given by the outside world. Clearly distinguish their respective responsibilities and powers, which is conducive to the optimization of the whole software architecture.
  • Disadvantages: obviously, the factory class centralizes the creation logic of all instances, which violates the opening and closing principle

2. Factory method model

The factory method pattern consists of four elements: abstract factory, concrete factory, abstract product and concrete product.

  • Abstract class or interface: it defines the specification of the Product and describes the main characteristics and functions of the Product. For example, in the example, the Product definition obtains automobile products
  • Concrete implementation: it implements the interface defined by the abstract Product role. For example, in the example, the implementation class of Product is mainly responsible for producing specific cars
  • Abstract factory: it provides an interface for creating products, through which callers access the factory methods of specific factories to create products. AbstractFactory defines how to create a product
  • Factory: it mainly realizes the methods in the abstract factory and completes the creation of specific products. AudiFactory implements AbstractFactory to create specific products
/**
 * Factory method model
 * @author liushiwei
 */
public class FactoryMethodDemo {

    public static void main(String[] args) {
        // Create factory
        AbstractFactory bmwFactory = new BmwFactory();
        // Get products
        Product product = bmwFactory.newProduct();
        // yield a product
        product.getProduct();


        // Get products
        AbstractFactory audiFactory = new AudiFactory();
        // Call product method
        Product audiProduct = audiFactory.newProduct();
        audiProduct.getProduct();

    }

}

/**
 * Define the interface of a product
 *    Method principle defined in design interface: it will not change due to product change
 * @author liushiwei
 */
interface Product{
    /**
     * Get products
     */
    public void getProduct();

}

/**
 * Benz
 */
class Benz implements Product{

    @Override
    public void getProduct() {
        System.out.println("Mercedes Benz");
    }
}

/**
 * bmw
 */
class Bmw implements Product{

    @Override
    public void getProduct() {
        System.out.println("BMW");
    }
}

/**
 * audi
 */
class Audi implements Product{

    @Override
    public void getProduct() {
        System.out.println("Audi");
    }
}

/**
 * Abstract factory
 */
interface AbstractFactory{

    /**
     * Obtain specific products
     * @return
     */
    public Product newProduct();
}

/**
 * Audi factory
 */
class AudiFactory implements AbstractFactory {

    @Override
    public Product newProduct() {
        return new Audi();
    }
}

/**
 * BMW factory
 */
class BmwFactory implements AbstractFactory {

    @Override
    public Product newProduct() {
        return new Bmw();
    }
}
  • characteristic

    • A product corresponds to a factory class, which is used to produce certain types of products
  • advantage

    • Easy to add new products
    • To add a new product, you only need to add the corresponding factory class, which complies with the opening and closing principle
  • shortcoming

    • When there are many products, factories are flooded.
  • getBean() method of BeanFactory in Spring

3. Abstract factory

Abstract factory pattern is to encapsulate a group of factories with the same theme. Abstract factory pattern is an upgraded version of factory method pattern. Factory method pattern only produces products of the same class (for example, multiple factories that only produce engines), while abstract factory pattern can produce products of multiple classes. For example, Audi factory can produce a series of product clusters such as engine, chassis, frame and so on

/**
 * Abstract factory
 * @author liushiwei
 */
public class FactoryMethodDemo {

    public static void main(String[] args) {
        // Create factory
        AbstractFactory audiFactory = new BenzFactory();
        // Create an engine workshop
        Engine engine = audiFactory.newEngine();
        // Create a chassis workshop
        Chassis chassis = audiFactory.newChassis();
        // Production engine
        engine.productionEngine();
        // Production chassis
        chassis.productionChassis();
    }
}

/**
 * engine
 */
abstract class Engine{
    /**
     * Production engine
     */
    public abstract void productionEngine();
}

/**
 * tyre
 */
abstract class Chassis{
    /**
     * Tire production
     */
    public abstract void productionChassis();
}


/**
 * Benz hair workshop
 */
class BenzEngine extends Engine{

    @Override
    public void productionEngine() {
        System.out.println("Production of Mercedes Benz engine");
    }
}

/**
 * Mercedes Benz chassis workshop
 */
class BenzChassis extends Chassis{

    @Override
    public void productionChassis() {
        System.out.println("Production of Mercedes Benz chassis");
    }
}

/**
 * Audi engine workshop
 */
class AudiEngine extends Engine{
    @Override
    public void productionEngine() {

        System.out.println("Production of Audi engine");
    }
}

/**
 * Audi engine workshop
 */
class AudiChassis extends Chassis{

    @Override
    public void productionChassis() {

        System.out.println("Production of Audi chassis");
    }
}
/**
 * Abstract factory
 */
abstract class AbstractFactory{

    /**
     * Engine workshop
     * @return
     */
    public abstract Engine newEngine();
    /**
     * Chassis workshop
     * @return
     */
    public abstract Chassis newChassis();
}


/**
 * Mercedes Benz factory
 */
class BenzFactory extends AbstractFactory {


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

    @Override
    public Chassis newChassis() {
        return new BenzChassis();
    }
}


/**
 * Audi factory
 */
class AudiFactory extends AbstractFactory {

    @Override
    public Engine newEngine() {
        return new AudiEngine();
    }

    @Override
    public Chassis newChassis() {
        return new AudiChassis();
    }
}

Whether it is simple factory mode, factory method mode or abstract factory mode, they all belong to factory mode and are very similar in form and characteristics. Their ultimate goal is to decouple. When using, we don't have to care whether this pattern is factory method pattern or abstract factory pattern, because the evolution between them is often elusive. You will often find that the factory method pattern used clearly becomes an abstract factory pattern when new requirements come and a new method is added. Since the products in the class constitute product families in different hierarchical structures, it becomes an abstract factory pattern; For the abstract factory pattern, when a method is reduced so that the products provided no longer form a product family, it evolves into the factory method pattern.

Keywords: Java Design Pattern

Added by wompas.dub on Thu, 10 Mar 2022 14:34:34 +0200