工厂模式以及在Spring中的应用

▼魔方 西西 提交于 2019-11-25 21:42:37

简单工厂模式

定义一个工厂类,根据参数的不同返回不同类的实例,被构建的实例通常具备共同的父类,属于类创建型模式。

  1. 首先抽象出产品的父类:
interface Vehicle {
    void run();
}
  1. 实现具体的产品类
class Car implements Vehicle {

    @Override
    public void run() {
        System.out.println("小汽车跑起来啊~~");
    }
}

class Bus implements Vehicle {

    @Override
    public void run() {
        System.out.println("公交车跑来了啊~~~");
    }
}

class Bicycle implements Vehicle {

    @Override
    public void run() {
        System.out.println("自行车跑起来啊~~~");
    }
}
  1. 实现一个工厂类,并写一个静态方法根据参数的不同返回不同的实例:
interface Factory {

    public static Vehicle product(String type) {

        Vehicle vehicle = null;
        switch (type) {
            case "car":
                vehicle = new Car();
                break;
            case "bus":
                vehicle = new Bus();
                break;
            case "bicycle":
                vehicle = new Bicycle();
                break;
            default:
                vehicle = new Car();
                break;
        }
        return vehicle;

    }

}
  1. 测试一下:
public class SimpleFactoryPattern {

    public static void main(String[] args) {

        Vehicle vehicle = Factory.product("bicycle");

        vehicle.run();
    }
}

简单工厂模式的优缺点总结:

  • 优点:
    1. Factory类包含必要的逻辑判断,可以根据参数的不同创建不同的实例,客户端免除了直接常见对象的职责,只管使用。实现了对象的创建和使用的分离。
    2. 客户端无需知道具体产品类的类名,只需要知道产品类对应的参数即可。
  • 缺点:
    1. Factory包含了所有产品的创建逻辑,职责过重,如果不能运行,全盘皆崩。
    2. 扩展性不好,一旦增加新的产品,就需要修改Factiry类,产品过多的情况下(几十万个产品甚至更多),想想Factory类是什么样的。
    3. 使用静态工厂方法,无法形成基于继承了等级结构。

工厂方法模式

针对简单工厂模式的缺点,在工厂方法模式中,不再提供统一的工厂类来创建所有的产品对象,而是针对不同的产品提供不同的工厂,提供一个和产品等级结构对应的工厂等级结构:

  1. 抽象产品类
interface Vehicle {
    void run();
}
  1. 抽象工厂类
interface Factory{
    Vehicle product();
}
  1. 创建产品具体类:
class Car implements Vehicle {

    @Override
    public void run() {
        System.out.println("小汽车跑起来啊~~");
    }
}
  1. 为具体的产品类对应的创建一个产品工厂类:
class CarFactory implements Factory {

    @Override
    public Vehicle product() {
        return new Car();
    }
}
  1. 此时我们需要添加产品,那么同样的道理,同时写两个具体类即可,如下增加了两个产品:
class Bus implements Vehicle {

    @Override
    public void run() {
        System.out.println("公交车跑来了啊~~~");
    }
}

class BusFactory implements Factory{

    @Override
    public Vehicle product() {
        return new Bus();
    }
}

class Bicycle implements Vehicle {

    @Override
    public void run() {
        System.out.println("自行车跑起来啊~~~");
    }
}
class BicycleFactory implements Factory{

    @Override
    public Vehicle product() {
        return new Bicycle();
    }
}
  1. 测试一下:
public class FactoryMethodPattern {

    public static void main(String[] args) {


        Factory factory = null;
        Vehicle vehicle = null;

        // 汽车
        factory = new CarFactory();
        vehicle = factory.product();
        vehicle.run();

        // 公交车
        factory = new BusFactory();
        vehicle = factory.product();
        vehicle.run();

        // 自行车
        factory = new BicycleFactory();
        vehicle = factory.product();
        vehicle.run();
    }

}
  • 在抽象工厂中,声明了工厂方法,并未实现,具体的产品对象工厂由客户自己实现,客户端面向抽象编程,可在运行时再指定具体工厂类。不同的工厂生产不同的产品。

Spring中的Bean工厂类

举个例子来说,比如AbstractFactoryBean中的getObject方法,是在父接口FactoryBean中定义的,然后在这里根据子类创建bean对象:

	@Override
	public final T getObject() throws Exception {
		if (isSingleton()) {
			return (this.initialized ? this.singletonInstance : getEarlySingletonInstance());
		}
		else {
			return createInstance();
		}
	}
标签