设计模式之工厂方法模式

使用工厂模式创建对象时,我们不需要对客户端暴露创建逻辑,只需要通过一个共同的接口(工厂)来创建即可,从而使得代码简洁易懂。

工厂方法模式中有以下几个元素:

  • 产品:要创建的对象
  • 工厂:用于创建产品的媒介

在介绍工厂方法模式之前,先介绍一下简单工厂 
简单工厂的实现十分简单:

  1. 共同的产品接口
  2. 产品类实现产品接口
  3. 提供工厂类,用于创建不同的产品

以生产汽车为例

1.共同的产品接口


public interface Car {
    void run();
}
2.具体的产品



public class Audi implements Car{

    @Override
    public void run() {
        System.out.println("Audi run");
    }
}
public class Byd implements Car {

    @Override
    public void run() {
        System.out.println("Byd run");
    }
}
3.创建工厂类,用于获取某一个具体的工厂 
以下两种方式获取创建工厂类 
方式一:通过传入字符串确定创建的产品



public class CarFactory {
    public static Car createCar(String type) {
        Car c = null;
        if ("Audi".equals(type)) {
            c = new Audi();
        } else if ("Byd".equals(type)) {
            c = new Byd();
        }
        return c;
    }
}
方式二:对每一种产品提供一个创建类



public class CarFactory {
    public static Car createByd() {
        return new Byd();
    }

    public static Car createAudi() {
        return new Audi();
    }
}
使用时,直接调用工厂类获取某个具体的产品



public static void main(String[] args) {
    Car car1 = CarFactory.createAudi();
    car1.run();

    Car car2 = CarFactory.createByd();
    car2.run();
}
简单工厂的结构十分简单易懂,但是从上例可以看出,简单工厂的扩展性很差。 
如果我们要增加一个产品,则必须


1. 添加一个产品类 2. 添加相应的工厂方法


针对这个缺点,工厂方法模式进行了改进,准确来说,是针对第2点进行了改进。 
上例中的产品接口和产品类我们暂时不修改,我们丢掉原来的工厂类,修改如下:

  1. 将工厂类接口化
  2. 具体的工厂生产具体的产品

1.工厂类接口化

public interface CarFactory {
    Car createCar();
}
2.具体的工厂生产具体的产品

public class AudiFactory implements CarFactory{

    @Override
    public Car createCar() {
        return new Audi();
    }
}
public class BydFactory implements CarFactory{

    @Override
    public Car createCar() {
        return new Byd();
    }
}
这样我们在调用的时候,只需要指定特定的工厂,就能产生相应的产品了

public static void main(String[] args) {
    Car car1 = new BydFactory().createCar();
    car1.run();

    Car car2 = new AudiFactory().createCar();
    car2.run();
}

如果要增加一件产品,在工厂方法模式中,只需要添加相应的实现类和实现工厂即可,不需要进入工厂类之中修改代码了。 
但是比较简单工厂可以看出,工厂方法模式的缺点在于扩展的时候需要改动的内容变多了,不够简洁

这里简单总结一下简单工厂和工厂方法模式 
简单工厂模式:

  • 工厂类一般使用静态方法,通过接收的参数的不同来返回不同的对象
  • 对于增加新产品无能为力,不修改代码的话,是无法扩展的。

工厂方法模式:

  • 避免了简单工厂模式的缺点,扩展性好,但较繁琐
  • 工厂方法模式和简单工厂模式的最大的不同在于,简单工厂模式只有一个(对于一个项目或者一个独立模块而言)工厂类,而工厂方法模式有一组实现了相同接口的工厂类