工厂方法模式(Factory Pattern) 是一种创建型设计模式 , 它是Java中最常用的设计模式之一 . 

1 . 工厂方法模式的定义

    定义一个创建对象的接口 , 让子类决定实例化哪一个类 . 工厂方法模式使一个类的实例化延迟到子类

2 . 工厂方法模式的特点

    将"类实例化的操作"和"使用对象的操作"分开 , 让使用者不用知道具体参数就可以实例化出所需要的"产品"类 , 从而避免了在代码中显式指定 , 实现了解耦 . 

3 . 工厂方法模式的实现思路

  1. 创建抽象产品接口 , 定义具体产品实例的方法
  2. 创建具体产品类(实现抽象产品接口) , 定义生产的具体产品
  3. 创建抽象工厂接口 , 定义具体工厂的通用接口
  4. 创建具体工厂类(实现抽象工厂接口) , 定义创建具体产品实例的方法
  5. 外界通过调用工厂类的方法 , 从而创建不同产品类的实例

4 . 工厂方法模式的应用场景

  1. 当一个类不需要知道它所需要的对象类别时
  2. 无序关注对象的内部实现时

5 . 代码实现

    1 . 简单工厂模式(工厂模式的变种很多 , 简单工厂模式就是工厂模式家族中最简单实用的一种模式) , 又叫做静态工厂方法模式(Static Factory Method) , 简单工厂模式是由一个工厂对象创建某一产品的实例 , 主要由三部分组成

  1. 工厂类角色 : 该模式的核心 , 用来创建产品 , 包含创建产品的相关逻辑和判断
  2. 抽象产品角色 : 指具体产品继承的父类或者实现的接口
  3. 具体产品角色 : 工厂类所创建的对象就是该角色的实例
/** 抽象产品接口 - 汽车 */
public interface ICar {
    void getCar();
}
/** 具体产品类 : 跑车 */
public class SportCar implements ICar{

    @Override
    public void getCar() {
        System.out.println("得到一辆跑车 . ");
    }
}

/** 具体产品类 : 越野车 */
class JeepCar implements ICar{

    @Override
    public void getCar() {
        System.out.println("得到一辆越野车 . ");
    }
}

/** 具体产品类 : 小货车 */
class BuggyCar implements ICar{

    @Override
    public void getCar() {
        System.out.println("得到一辆小货车 . ");
    }
}
/** 简单工厂核心类 :  */
public class SimpleFactory {
    public static final int CAR_TYPE_SPORT = 1;
    public static final int CAR_TYPE_JEEP= 2;
    public static final int CAR_TYPE_BUGGY = 3;

    public static ICar getCar(int carType){
        if(carType == CAR_TYPE_SPORT){
            return new SportCar();
        }else if(carType == CAR_TYPE_JEEP){
            return new JeepCar();
        }else if(carType == CAR_TYPE_BUGGY){
            return new BuggyCar();
        }else{
            throw new RuntimeException("啥车都没找到");
        }
    }
}
/** 调用工厂方法 */
public class SimpleFactoryDemo {
    public static void main(String[] args) {
        System.out.println("来到汽车工厂 , 准备取车 : ");
        try {
            ICar car =SimpleFactory.getCar(SimpleFactory.CAR_TYPE_SPORT);
            car.getCar();
        }catch (Exception e){
            System.out.println(e.getMessage());
        }
    }
}

    调用者不再关注实例化什么对象 , 只需要将需求告诉工厂类 , 工厂类就会实例化相应的类 , 调用者不需要知道生产的细节就可以使用产品

2 . 综上述代码来看 , 不难发现简单工厂模式存在一系列问题 : 

  1. 工厂类集中了所有实例的创建逻辑 , 一旦这个工厂不能正常工作 , 整个系统都会受到影响 . 
  2. 违背"开放-关闭"原则 , 一旦添加新产品就不得不修改工厂类的逻辑 , 造成工厂类过于臃肿 . 
  3. 简单工厂模式由于使用了静态工厂方法 , 静态方法不能被继承和重写 , 会造成工厂角色无法形成基于继承的等级结构 . 

为了解决以上问题 , 我们又使用了新的工厂方法模式 . 工厂方法模式相对简单工厂模式多了一个角色

  • 抽象工厂角色 : 与生产过程无关 , 任何在模式中创建的工厂类必须实现这个接口

抽象产品接口和产品实例类与之前一样 , 其他类代码如下

/** 抽象工厂接口 */
public interface IFactoryMethod{
    ICar createCar();
}
/** 工厂实现类 */
public class SportFactory implements IFactoryMethod{
    @Override
    public ICar createCar() {
        return new SportCar();
    }
}

class JeepFactory implements IFactoryMethod{
    @Override
    public ICar createCar() {
        return new JeepCar();
    }
}

class BuggyFactory implements IFactoryMethod{
    @Override
    public ICar createCar() {
        return new BuggyCar();
    }
}
/** 调用工厂方法 */
public class FactoryMethodDemo {
    public static void main(String[] args) {
        System.out.println("来到汽车工厂 , 准备取车 : ");
        IFactoryMethod factory1 = new SportFactory();//A工厂
        ICar car1 = factory1.createCar();
        System.out.print("A取车 : ");
        car1.getCar();

        IFactoryMethod factory2 = new JeepFactory();//B工厂
        ICar car2 = factory2.createCar();
        System.out.print("B取车 : ");
        car1.getCar();
    }
}

6 . 总结

  1. 单一职责
  2. 开闭原则
  3. 调用者无需关心实现