模式动机
设想一个简单的场景,现在有一家专门生产汽车的工厂,可以生产奔驰(Benz)和宝马(BMW)。我现在不想知道这些汽车是如何生产出来的,也就是不想了解生产汽车的具体细节,只想简单的通过传入一个参数,比如汽车的名称,这个工厂便能返回一辆与之对应的汽车。如下图:
模式定义
简单工厂模式又叫静态工厂模式。首先,它并不属于23种GOF模式,23种GOF中只有工厂模式和抽象工厂模式,但简单工厂模式是工厂模式和抽象工厂模式的基础,能更有助于我们理解后面两者。简单工厂模式的主要目的是通过不同参数获取不同类的实例,它的主要实现原理是专门定义一个工厂类,来创建其他类的实例,被创建的实例通常拥有共同的父类。
模式结构
简单工厂模式主要由以下三部分组成:
产品接口类:如ICar
具体产品类:如BenzCar,BMWCar
工厂类:如CarFactory
代码实现
汽车接口类
public interface ICar {
public abstract String getName();
}
具体汽车类
public class BenzCar implements ICar {
@Override
public String getName() {
return "奔驰";
}
}
public class BMWCar implements ICar {
@Override
public String getName() {
return "宝马";
}
}
汽车工厂类
public class CarFactory {
public static ICar produce(String carName){
if("Benz".equals(carName)){
return new BenzCar();
}else if("BMW".equals(carName)){
return new BMWCar();
}else{
return null;
}
}
}
客户端测试
public class Client {
public static void main(String[] args) {
ICar car1 = CarFactory.produce("Benz");
ICar car2 = CarFactory.produce("BMW");
System.out.println(car1.getName());
System.out.println(car2.getName());
}
}
运行客户端测试类,控制台输出为
奔驰
宝马
模式优缺点
优点
- 将对象的创建和使用进行分离,使用时不需要知道创建的具体细节,降低了系统的耦合度
- 实际开发中,可以将传入的参数配置到xml、properties等配置文件中,修改参数时不需要修改源代码,提高了系统灵活性
缺点
- 由于只有一个工厂类,所有的产品创建逻辑都在里面,一旦这个工厂类无法工作,则会影响所有产品的创建工作。比如在我们的例子中,一旦CarFactory出现了问题,那Benz跟BMW都有可能受到影响
- 一旦添加新的产品,还得修改工厂类的逻辑,修改源码,如果产品过多时,可能造成工厂的逻辑变得复杂,不利于维护和扩展。比如在我们的例子中,突然有一天还需要生产奥迪(Audi),那就得改CarFactory的逻辑,这个是违背开闭原则的。
备注:简单工厂模式的缺点,会在下一个模式(工厂模式)中得到解决
适用场景
- 工厂类负责创建的对象较少,这样工厂类里的业务逻辑不会太复杂,便于维护
- 客户端不关心对象创建的具体细节,只需要传入对应参数
总结
这个模式相对比较简单,就一句话:我有一个汽车厂,帮我生产汽车吧!