一. 准备工作
1. 本文参考自 自己理解的工厂模式,希望对大家有所帮助
二. 开始
以汽车工厂为例,首先有个汽车类的接口 Car,里面有个开车的方法 drive(),然后有个宝马车的类 BMW 和奔驰车的类 Benz 实现了 Car 接口。
public interface Car{ public void drive(); } public class BMW implements Car{ public BMW(){ System.out.println("生产一台宝马车"); } public void drive(){ System.out.println("我开宝马车"); } } public class Benz implements Car{ public Benz(){ System.out.println("生产一台奔驰车"); } public void drive(){ System.out.println("我开奔驰车"); } }
现在如果要用 BMW 这个类,最基本的方法是:BMW bmw = new BMW(); 如果还要个 Benz 类,就得:new Benz();这样每个都得 new 个汽车对象,但是宝马和奔驰都属于汽车,都有 drive() 方法;那我们是不是能创建一个生产汽车的工厂,然后想要什么汽车告诉工厂,工厂帮你生产就可以了,而不用管生产的细节(也就是 new 对象的过程),这样会更好呢?到此,简单工厂模式就出来了。
三. 简单工厂模式
public class CarFactory{ public static Car createCar(String carName){ if("BMW".equals(carName)){ return new BMW(); }else if("Benz".equals(carName)){ return new Benz(); } } }
如果要生产一台汽车,直接调用Car car = CarFactory.createCar("BMW"); 就可以了。
这种工厂虽然挺好,但是每次要加入新车都得修改工厂类来加入新的判断语句,不符合开闭原则;所以又有了一种更好的生产方式,这就是工厂方法模式。
四. 工厂方法模式
首先抽象出一个生产汽车的工厂类接口,然后让具体工厂类实现这个接口,这样就有宝马车生产工厂、奔驰车生产工厂。
public interface CarFactory{ public static Car createCar(); } public class BMWFactory implements CarFactory{ public static Car createCar(){ return new BMW(); } } public class BenzFactory implements CarFactory{ public static Car createCar(){ return new Benz(); } }
这样的好处就是如果我还要生产长城汽车,不用去修改 CarFactory 工厂,只要写个长城工厂类去实现CarFactory接口就可以了。
随着社会的进步,汽车种类也多了,比如分为越野车和跑车两个系列,这样原来 Car 接口就不能通用,而变成 YueYeChe 和 PaoChe 两个接口,而越野车适合在山上跑,跑车适合在赛路上跑,drive 的方法也改变了,如下:
public interface YueYeChe{ public void driveShanLu(); } public interface PaoChe{ public void driveSaiLu(); }
而宝马和奔驰都生产跑车和越野车:
public BMWYueYeChe implements YueYeChe{ public void driveYueYeChe(){ System.out.println("我在山路上开宝马越野车"); } } public BMWPaoChe implements PaoChe{ public void drivePaoChe(){ System.out.println("我在赛路上开宝马跑车"); } } public BenzYueYeChe implements YueYeChe{ public void driveYueYeChe(){ System.out.println("我在山路上开奔驰越野车"); } } public BenzPaoChe implements PaoChe{ public void drivePaoChe(){ System.out.println("我在赛路上开奔驰跑车"); } }
按照工厂方法模式,我们需要 YueYeCheFactory 和 PaoCheFactory 两个工厂接口,以及 BMWYueYeCheFactory 、BMWPaoCheFactory、BenzYueYeCheFactory 、BenzPaoCheFactory 四个具体工厂类。如果需要再生产其他车,工厂类会呈指数增长,难以维护。如果能对工厂接口进行扩充,不是更好?这样就产生了抽象工厂模式。
五. 抽象工厂模式
工厂方法模式一般是针对一种系列的抽象产品的生产,为变成可以对多种系列的产品进行生产,而把工厂方法模式进行扩充,这就是抽象工厂模式。因为 Car 类分成了跑车和越野车,所以扩充后的工厂接口也就能生产出跑车和越野车。这样,宝马工厂类可以生产宝马跑车和宝马越野车,奔驰工厂类可以生产奔驰跑车和奔驰越野车。
public interface CarFactory{ public static PaoChe createPaoChe(); public static YueYeChe createYueYeChe(); } public BMWFactory implements CarFactory{ public static PaoChe createPaoChe(){ return new BMWPaoChe(); } public static YueYeChe createYueYeChe(){ return new BMWYueYeChe(); } } public BenzFactory implements CarFactory{ public static PaoChe createPaoChe(){ return new BenzPaoChe(); } public static YueYeChe createYueYeChe(){ return new BenzYueYeChe(); } }