工厂模式,是各种开源框架中常用的设计模式,比如spring的ioc,log4j等。
工厂模式有三种,简单工厂模式,工厂方法模式,抽象工厂模式,下面我们一一介绍,
- 简单工厂模式
简单工厂模式就是工厂模式最简单的用法,缺点比较明显,可扩展性不好,解耦性不强,不符合开闭原则和职责单一原则,
可以理解为简单工厂模式就是一个小作坊,来什么订单,我就做什么,没有工具我就去现买工具。下面我通过代码来看。
//先定义汽车接口和汽车类
public interface ICar {
}
public class DaZhongCar implements ICar {
}
public class BenCiCar implements ICar {
}
//我们开了一个汽车厂,要生产汽车。
public class CarFactory {
//这里用户通过汽车的名字告诉我们,我要生产什么牌子的汽车
public static ICar getCarByCarName(String carName) {
if ("Dazhong".equals(carName)) {
System.out.println("收到了大众的订单");
return new DaZhongCar();
}
if ("Benci".equals(carName)) {
System.out.println("收到了奔驰的订单");
return new BenCiCar();
}
return null;
}
//这里用户通过汽车的类型告诉我们,我要生产什么牌子的汽车
public static ICar getCarByType(String carType) {
try {
Class carClazz = Class.forName(carType);
System.out.println("收到了" + carType + "的订单");
if (carClazz != null) {
return (ICar) carClazz.newInstance();
}
} catch (ClassNotFoundException | IllegalAccessException | InstantiationException e) {
e.printStackTrace();
}
return null;
}
}
我们可以看到,如果订单来了我们可以做这个汽车,那就生产汽车,如果不行,那就没有办法了,只能去改代码,增加新的方法,增加新的判断。这完全不符合开闭原则。而且一个工厂又可以生产奔驰的汽车还可以生产大众的汽车,这也不符合职责单一原则。但是他的优点是 用户看不到我们生产的过程,他需要下订单,不需要管汽车是怎么来的,只需要直接跟工厂对接就OK了,这就是简单工厂模式。接下来看符合开闭原则和职责单一原则的工厂方法模式。
工厂方法模式可以理解为对简单工厂模式的完善,我们从上面的代码引申一下,我们定义一个工厂接口,接口里定义一个方法,所有的工厂都要实现这个接口。接下来还是看代码
//定义一个接口
public interface ICarFactory {
ICar getCar();
}
//定义奔驰的工厂只生产奔驰车
public class BenciCarFactory implements ICarFactory {
@Override
public ICar getCar() {
System.out.println("我是奔驰的工厂,收到了订单");
return new BenCiCar();
}
}
//定义大众的工厂,只生产大众车
public class DazhongCarFactory implements ICarFactory {
@Override
public ICar getCar() {
System.out.println("我是大众的工厂,收到了订单");
return new DaZhongCar();
}
}
ok,从代码我们可以看出来了吧,如果再有奥迪的订单,就创建一个奥迪的工厂,不需要修改奔驰和大众的工厂了就,完全符合开闭原则和职责单一原则,但是有个缺点就是会有好多个工厂,不过没有完美的设计模式,所有的设计模式都是由缺点的,然后我们接下来看抽象工厂模式。
抽象工厂模式 是这样的,现在我们有了一个新的订单,不是大众车,也不是奔驰车,但是这个订单需要大众车的发动起和奔驰车的轮胎。这就需要细化生产过程了。然后还是看代码。
public interface ICarFactory {
//生产发动机
IEngine createEngine();
//生产轮胎
IShoe createShoe();
}
//奔驰车厂
public class BenciICarFactory implements ICarFactory {
@Override
public IEngine createEngine() {
System.out.println("收到了发动机的订单,创建奔驰的发动机");
return new BenciEngine();
}
@Override
public IShoe createShoe() {
System.out.println("收到了轮胎的订单,创建奔驰的发动机");
return new BenciShoe();
}
}
//大众车厂
public class DazhongCarFactory implements ICarFactory {
@Override
public IEngine createEngine() {
System.out.println("收到了发动机的订单,创造大众车的发动机");
return new DazhongEngine();
}
@Override
public IShoe createShoe() {
System.out.println("收到了轮胎的订单,创造大众车的轮胎");
return new DazhongShoe();
}
}
上面的代码我们可以看到了,工厂现在不生产车了,而是生产零件,这样的话,就可以完成这个组装车的订单了。抽象工厂模式主要是解决了一个产品族和产品等级结构的问题。同样有缺点,也不符合开闭原则,每当有个新零件的时候,我们需要修改工厂的接口,而且要修改全部的工厂类,是个很大的工程,所以这个抽象工厂模式一定要慎用!!然后给出uml图