三大工厂模式
一丶简单工厂模式
简单工厂的特点就是需要在工厂中做相应的判断来生产指定对象,对于客户端来说,去除了具体的类的依赖。只需要给出具体实例的描述给工厂,工厂就会自动返回具体的实例对象。
abstract class Car{ abstract void run(); } class Benz extends Car{ String name; public Benz() { super(); } public Benz(String name) { super(); this.name = name; } void run() { System.out.println(name + " is running"); } } class Audi extends Car{ String name; public Audi() { super(); } public Audi(String name) { super(); this.name = name; } void run() { System.out.println(name + " is running"); } } public void simpleFactory(String type){ Scanner scan = new Scanner(System.in); type = scan.nextLine(); Car car = null; if("audi".equals(type)){ car = new Audi("audi"); }else if("benz".equals(type)){ car = new Benz("benz"); }else{ System.out.println("我们不生产"); } car.run(); scan.close(); }
但是这种工厂的问题也很明显就是每次增加一个新的产品都要在代码里增加一个业务逻辑的判断,这会导致这个简单工厂类很庞大臃肿、耦合性高,而且增加、删除某个子类对象的创建都需要打开简单工厂类来进行修改代码也违反了开-闭原则。
二丶工厂模式
于是工厂模式就诞生了。
所谓工厂方法模式,是指定义一个用于创建对象的接口,让子类决定实例化哪一个类。Factory Method使一个类的实例化延迟到其子类。
听起来很抽象,还是以刚才的例子解释。这家生产汽车产家赚了不少钱,于是决定再开设一个工厂专门用来生产奔驰,而原来的工厂专门用来生产奥迪。这时,客户要做的是找好工厂,比如要奥迪车,就找奥迪工厂要;否则找B工厂要,不再需要告诉工厂具体要什么型号的处理器核了。下面给出一个实现方案。
abstract class CarFactory{ abstract Car getCar(); } class AudiFactory extends CarFactory{ Car getCar() { return new Audi(); } } class BenzFactory extends CarFactory{ Car getCar() { return new Benz(); } } public void factory() { CarFactory audiFactory = new AudiFactory(); CarFactory benzFactory = new BenzFactory(); // 通过工厂对象创建相应的实例对象 Car audi = audiFactory.getCar(); Car benz = benzFactory.getCar(); }
这样以后生产新的汽车只要继承CarFactory类,写相应得实现类,不需要在原来得类上进行改动。符合了开放-闭合原则,又保持了封装对象创建过程的优点。
但工厂方法模式的缺点是每增加一个产品类,就需要增加一个对应的工厂类,增加了额外的开发量。
三丶抽象工厂
抽象工厂模式它到底有什么作用呢?还是举这个例子,公司的壮大后,光生产小汽车不够,也要能生产巴士。现在简单工厂模式和工厂方法模式都鞭长莫及。抽象工厂模式登场了。它的定义为提供一个创建一系列相关或相互依赖对象的接口,而无需指定它们具体的类。这家公司还是开设两个工厂,一个专门用来生产audi小汽车和巴士,而另一个工厂专门用来生产benz的小汽车和巴士,下面给出实现的代码。
abstract class Car{ } class BenzCar extends Car{ } class AudiCar extends Car{ } abstract class Bus{ } class BenzBus extends Bus{ } class AudiBus extends Bus{ } abstract class AbstractFactory{ abstract Car getCar(); abstract Bus getBus(); } class AudiFactory extends AbstractFactory{ Car getCar() { return new AudiCar(); } Bus getBus() { return new AudiBus(); } } class BenzFactory extends AbstractFactory{ Car getCar() { return new BenzCar(); } Bus getBus() { return new BenzBus(); } } public void factory(){ AbstractFactory audiFactory = new AudiFactory(); AbstractFactory benzFactory = new BenzFactory(); Car audiCar = audiFactory.getCar(); Bus audiBus = audiFactory.getBus(); Car benzCar = benzFactory.getCar(); Bus benzBus = benzFactory.getBus(); }
在抽象工厂模式中,假设我们需要增加一个工厂
假设我们增加宝马工厂,则我们需要增加宝马工厂继承抽象工厂。
之后创建宝马汽车继承汽车类,创建宝马巴士继承巴士类即可。
在抽象工厂模式中,假设我们需要增加一个产品
假设我们增加SUV这个产品,则首先我们需要增加SUV这个父类,新建两个AudiSuv和BenzSuv继承这个父类。
在抽象工厂中新增abstract Suv getSuv();这个抽象方法,让奥迪和奔驰工厂实现这个方法。
所以抽象工厂与工厂方法模式的区别在于:抽象工厂是可以生产多个产品的,例如 AudiFactory 里可以生产 Car 以及 Bus两个产品,而这两个产品又是属于一个系列的,因为它们都是属于Audi。而工厂方法模式则只能生产一个产品,例如之前的 AudiFactory 里就只可以生产一个 Car 产品。