工厂模式通常分为简单工厂、工厂方法和抽象工厂三种,看了不少资料,好多讲的都是云里雾里的。要么是概念太多,让人看得一脸懵逼,要么是举得例子不太恰当,看了更让人迷惑了。通过本身一番研究,经过一个简单的例子,终于搞明白了它们之间的区别。ide
下面以生产宝马、奔驰汽车的工厂为例,讲解它们之间的区别。设计
1、简单工厂模式code
建立一个工厂类,根据传入的参数来决定建立哪一个汽车类对象
//汽车接口 public interface Car { void getCar(); } //宝马汽车类 public class BMWCar implements Car { @Override public void getCar() { System.out.println("这是宝马车"); } } //奔驰汽车类 public class BenzCar implements Car { @Override public void getCar() { System.out.println("这是奔驰车"); } } //工厂类,用于决定建立哪个具体的汽车类 public class DefaultFactory { public Car produce(String name){ if(name.equals("benz")){ return new BenzCar(); }else if(name.equals("bmw")){ return new BMWCar(); } return null; } } public class FTest { public static void main(String[] args) { DefaultFactory factory = new DefaultFactory(); Car car = factory.produce("bmw"); car.getCar(); //这是宝马车 Car benz = factory.produce("benz"); benz.getCar(); //这是奔驰车 } }
能够看到,在具体的工厂类DefaultFactory中,咱们根据传入的name来决定建立哪个汽车类。当须要建立宝马时,传入bmw,当须要建立奔驰时传入benz。思考一下,若是我须要建立一个大众汽车呢。是否是须要建立一个大众汽车类实现Car接口,还须要修改工厂类的produce方法,新增一个大众的分支。 再回忆一下,以前讲过的软件六大设计原则之一开闭原则。很明显,这违背了开闭原则(对修改是关闭的)。blog
因而,有了下边的工厂方法,能够保证遵循开闭原则。接口
2、工厂方法模式get
工厂方法,相比于简单工厂,多了一个角色——工厂接口,负责定义生产汽车的公共接口,而后每一个工厂实现类都去实现这个接口。产品
//工厂接口 public interface IFactory { Car produce(); } //宝马生产工厂 public class BMWFactory implements IFactory{ @Override public Car produce() { return new BMWCar(); } } //奔驰生产工厂 public class BenzFactory implements IFactory { @Override public Car produce() { return new BenzCar(); } } public class FacTest { public static void main(String[] args) { BMWFactory bmwFactory = new BMWFactory(); bmwFactory.produce().getCar(); //这是宝马车 BenzFactory benzFactory = new BenzFactory(); benzFactory.produce().getCar(); //这是奔驰车 } }
能够看到,我把以前的一个工厂,拆分为两个工厂。当具体须要哪一个汽车的时候,就去实例化它对应的工厂。这样,当再须要大众车的时候,我只须要添加一个大众车的类和大众车对应的工厂实现类去实现IFactory接口就能够了。不须要修改原来的代码,这就符合开闭原则了。class
3、 抽象工厂模式扩展
初识抽象工厂的同窗,老是很迷惑它和工厂方法有什么区别,不就是在工厂实现类里多了几个方法吗。其实,抽象工厂是对工厂方法的升级,用于建立一组相互关联或相互依赖的对象。
在此须要了解一下产品等级和产品族的关系。假若有一个汽车制造商,它只生产低配版的汽车产品(至于为何,我猜是低配版更亲民,销量更高吧,哈哈),其中就包括低配宝马和低配奔驰。还有一个汽车制造商只生产高配版的汽车(没什么缘由,就是钱多任性,高端大气上档次),如高配宝马和高配奔驰。
咱们就把高配制造商或者低配制造商称为一个产品族。而其中的低配宝马和低配奔驰属于同一个产品等级,高配宝马和高配奔驰属于同一个产品等级。
画一张图来理解一下它们的概念,横向是三个产品族,纵向是两个产品等级。
代码以下:
//工厂接口,包含两个方法,建立宝马和建立奔驰 public interface IFactory { Car produceBMW(); Car produceBenz(); } //-------- 高配车和工厂实现类 -------// public class HighBMW implements Car { @Override public void getCar() { System.out.println("高配宝马车"); } } public class HighBenz implements Car { @Override public void getCar() { System.out.println("高配奔驰车"); } } public class HighFactory implements IFactory { @Override public Car produceBMW() { return new HighBMW(); } @Override public Car produceBenz() { return new HighBenz(); } } //-------- 低配车和工厂实现类 ----------// public class LowBMW implements Car { @Override public void getCar() { System.out.println("低配宝马车"); } } public class LowBenz implements Car { @Override public void getCar() { System.out.printf("低配奔驰车"); } } public class LowFactory implements IFactory { @Override public Car produceBMW() { return new LowBMW(); } @Override public Car produceBenz() { return new LowBenz(); } } public class AbsTest { public static void main(String[] args) { HighFactory highFactory = new HighFactory(); highFactory.produceBMW().getCar(); //高配宝马车 highFactory.produceBenz().getCar(); //高配奔驰车 LowFactory lowFactory = new LowFactory(); lowFactory.produceBMW().getCar(); //低配宝马车 lowFactory.produceBenz().getCar(); //低配奔驰车 } }
乍一看,抽象工厂和工厂方法特别的类似,其实这里边就是多了一个产品族的概念,它强调一个产品族的对象应该放到同一个工厂类里边。好比,我再须要一个中配版或者豪华版的汽车制造商,只须要实现它的具体工厂类和相应的各同等级的汽车类。
总结: