不断的学习,我们才能不断的前进
一个好的程序员是那种过单行线马路都要往两边看的人

JAVA设计模式--工厂模式

1. 简介

  • 工厂方法(Factory Method)模式是类的创建模式,它通过定义一个用于创建对象的接口,让子类决定实例化哪一个类,使一个类的实例化延迟到其子类。(工厂方法又称为虚构造器)。
  • 简单工厂模式属于创建型模式,属于工厂模式中的一种,简单工厂模式就是由一个工厂对象来决定创建出一种具体的产品
  • 在简单工厂模式中,我们会定义一个创建对象的类,多使用反射的方法来创建具体产品实例,这个类用来封装实例化对象的行为。
  • 在软件开发中,当我们需要大量的创某种,某类或者某一批对象时候,就可以考虑使用简单工厂模式

2. 模式的适用性

  1. 当一个类不知道它所必须创建的对象的类的时候。
  2. 当一个类希望由它的子类来指定它所创建的对象的时候。
  3. 当类将创建对象的职责委托给多个帮助子类中的某一个,并且你希望将哪一个帮助子类是代理者这一信息局部化的时候。

3. 为什么要使用工厂模式

  1. 为了解藕,把对象的创建和使用过程分开
  2. 减少重复的代码,对象的创建放在工厂里面,使用者只需要调用即可

4. 具体的使用过程

  1. 抽象产品接口
  2. 具体产品实现类
  3. 抽象工厂类
  4. 具体实现工厂类

5. 优点和缺点

优点:实现了解藕,用户只需要知道产品的工厂,不需要知道具体的实现细节;符合开闭原则,新增产品不需要修改工厂和抽象类,只需要新增一个工厂和产品
缺点:类的个数会增加,在工厂创建实例化的过程中可以使用反射,枚举,java8提供的函数接口,增加类系统的复杂性。

6. 工厂方法的实例

/**
 * @Author laijinhan
 * @date 2020/9/12 12:27 下午
 */

import lombok.NoArgsConstructor;
import java.util.function.Supplier;

/**
 * 抽象产品类
 */
interface Pizza{
    void prepare();
}

/**
 * 具体的产品类
 */
@NoArgsConstructor
class CheesePizza implements Pizza{
    @Override
    public void prepare(){
        System.out.println("芝士披萨开始准备。。。");
    }
}
/**
 * 具体的产品类
 */
@NoArgsConstructor
class FruitPizza implements Pizza{
    @Override
    public void prepare(){
        System.out.println("水果披萨开始准备。。。");
    }
}

/**
 * 产品枚举类
 */
enum PizzaEnum{
    CHEESE(CheesePizza::new),
    FRUIT(FruitPizza::new);

    private final Supplier<Pizza> constructor;

    PizzaEnum(Supplier<Pizza> constructor) {
        this.constructor = constructor;
    }

    public Supplier<Pizza> getConstructor() {
        return constructor;
    }

}

public class FactoryMode {
    /**
     *
     *简单工厂类
     */
    public static class SimpleFactory{
        public static <T extends Pizza>T createPizza1(Class<T> t){
            Pizza pizza=null;
            try{
                pizza=(Pizza) Class.forName(t.getName()).newInstance();
            }catch (Exception e){
                System.out.println(String.format("生产披萨出错。。{}", e));
            }
            return (T) pizza;
        }
        public static Pizza createPizza(PizzaEnum pizzaEnum) {
            return pizzaEnum.getConstructor().get(); //get方法会调用对象的构造方法,获得真正的对象
        }
    }
    public static void main (String[] args){
        System.out.println("反射实现工厂模式:");
        CheesePizza cheesePizza1 = SimpleFactory.createPizza1(CheesePizza.class);
        FruitPizza fruitPizza1 = SimpleFactory.createPizza1(FruitPizza.class);
        cheesePizza1.prepare();
        fruitPizza1.prepare();

        System.out.println("枚举实现工厂模式:");
        Pizza cheesePizza = SimpleFactory.createPizza(PizzaEnum.CHEESE);
        Pizza fruitPizza = SimpleFactory.createPizza(PizzaEnum.FRUIT);
        cheesePizza.prepare();
        fruitPizza.prepare();
    }

}

使用场景

JDK中的java.util.Calendar#getInstance()使用了抽象工厂模式。

JDK中的java.lang.Object#toString()使用了工厂方法模式。

Spring中的FactoryBean使用了工厂方法模式。

Mybatis中的SqlSessionFactory使用了工厂方法模式。

参考链接


目录