简单工厂模式
定义一个工厂类,根据参数的不同返回不同类的实例,被构建的实例通常具备共同的父类,属于类创建型模式。
首先抽象出产品的父类:
interface Vehicle {
void run();
}
实现具体的产品类
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("自行车跑起来啊~~~");
}
}
实现一个工厂类,并写一个静态方法根据参数的不同返回不同的实例:
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;
}
}
测试一下:
public class SimpleFactoryPattern {
public static void main(String[] args) {
Vehicle vehicle = Factory.product("bicycle");
vehicle.run();
}
}
简单工厂模式的优缺点总结:
优点:
Factory类包含必要的逻辑判断,可以根据参数的不同创建不同的实例,客户端免除了直接常见对象的职责,只管使用。实现了对象的创建和使用的分离。
客户端无需知道具体产品类的类名,只需要知道产品类对应的参数即可。
缺点:
Factory包含了所有产品的创建逻辑,职责过重,如果不能运行,全盘皆崩。
扩展性不好,一旦增加新的产品,就需要修改Factiry类,产品过多的情况下(几十万个产品甚至更多),想想Factory类是什么样的。
使用静态工厂方法,无法形成基于继承了等级结构。
工厂方法模式
针对简单工厂模式的缺点,在工厂方法模式中,不再提供统一的工厂类来创建所有的产品对象,而是针对不同的产品提供不同的工厂,提供一个和产品等级结构对应的工厂等级结构:
抽象产品类
interface Vehicle {
void run();
}
抽象工厂类
interface Factory{
Vehicle product();
}
创建产品具体类:
class Car implements Vehicle {
@Override
public void run() {
System.out.println("小汽车跑起来啊~~");
}
}
为具体的产品类对应的创建一个产品工厂类:
class CarFactory implements Factory {
@Override
public Vehicle product() {
return new Car();
}
}
此时我们需要添加产品,那么同样的道理,同时写两个具体类即可,如下增加了两个产品:
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();
}
}
测试一下:
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();
}
}