Java工厂模式的深入了解
作者:空山新雨后~
一、简单工厂模式
何为简单工厂模式?
首先先通过一个案例来理解
我有一个需求,要买车,买车有不同的型号,那么我们常见的做法就是我买车点有什么车我就买什么车,实例如下
定义一个车接口
public interface Car { void name(); }
定义一个实现类,例如宝马
public class Baoma implements Car { @Override public void name() { System.out.println("宝马"); } }
测试
public class Test { public static void main(String[] args) { Car car3 = new Baoma(); car3.name();
结果:宝马
很显然这并不符合我们工厂设计模式的思想,我们不应该让用户去new一个车出来,现实生活中也不可能自己去new一个车然后自己买,对不对,因此我们要设计一个简单的工厂来满足我们的需求,
简单工厂类
public class CarFactory { public static Car getCar(String car) { if(car.equals("宝马")) { return new Baoma(); }else if(car.equals("奥迪")) { return new AoDI(); } return null; } }
测试
Car car = CarFactory.getCar("宝马"); car.name(); Car car1 = CarFactory.getCar("奥迪"); car1.name();
结果:宝马 奥迪
那么此时我们用户就不需要去关心我们的车是怎么来的,车该怎么造出来,造出来是什么车,我用户只管从工厂中去拿出我们需要的车即可,如果没有,再从工厂中去添加
该图是对简单工厂模式的一个辅助理解。
总结一下,简单工厂模式: 用来生产同一等级结构中的任意产品(对于增加新的产品,需要覆盖已有代码)
二、工厂方法模式
那么在简单工厂类大家应该发现了一个问题,如果我们需要添加一辆新车,就需要进入工厂修改工厂的代码,如果我们修改了我们的代码,那么久违反了我们设计模式的开闭原则,不好,那么我们就来到了我们的工厂方法模式。
何为工厂方法模式,示例如下:
其中车类和车接口不变,我们改变一下车工厂
我们定义一个车接口,方法返回一辆车
public interface CarFactory { Car getCar(); }
那么我们可以想就是给每个车都配一个车工厂,那么添加的时候,只需要在新添加一个车工厂,去实现这个车工厂接口即可
奥迪工厂
public class AoDIFactory implements CarFactory{ @Override public Car getCar() { return new AoDI(); } }
宝马工厂我就不演示了。
测试
Car baoma = new BaoMaFactory().getCar(); Car Aodi = new AoDIFactory().getCar(); baoma.name(); Aodi.name();
那么此时如果我们要添加新车,我们只需要去添加他的车以及他的工厂即可,用户则只需要去找对应的工厂
总结一下,
工厂方法模式:用来生产同一等级结构中的固定产品(支持增加任意产品)
三、抽象工厂模式
前面介绍的工厂方法模式中考虑的是一类产品的生产,如畜牧场只养动物、电视机厂只生产电视机、计算机软件学院只培养计算机软件专业的学生等。
同种类称为同等级,也就是说:工厂方法模式中只考虑生产同等级的产品,但是在现实生活中许多工厂是综合型的工厂,能生产多等级(种类) 的产品,如农场里既养动物又种植物,电器厂既生产电视机又生产洗衣机或空调,大学既有软件专业又有生物专业等。
这里需要先了解一个定义:
产品族:将同一个具体工厂所生产的位于不同等级的一组产品称为一个产品族
如图所示
3.1、抽象工厂模式的定义
是一种为访问类提供一个创建一组相关或相互依赖对象的接口,且访问类无须指定所要产品的具体类就能得到同族的不同等级的产品的模式结构。
使用抽象工厂模式一般要满足以下条件
可以在类的内部对产品族中相关联的多等级产品共同管理,而不必专门引入多个新的类来进行管理。
当需要产品族时,抽象工厂可以保证客户端始终只使用同一个产品的产品组。
抽象工厂增强了程序的可扩展性,当增加一个新的产品族时,不需要修改原代码,满足开闭原则。
当然使用抽象工厂模式也是有缺点的:
当产品族中需要增加一个新的产品时,所有的工厂类都需要进行修改。增加了系统的抽象性和理解难度。
3.2、 抽象工厂模式的结构
1. 抽象工厂(Abstract Factory):提供了创建产品的接口,它包含多个创建产品的方法 newProduct(),可以创建多个不同等级的产品。
2. 具体工厂(Concrete Factory):主要是实现抽象工厂中的多个抽象方法,完成具体产品的创建。
3. 抽象产品(Product):定义了产品的规范,描述了产品的主要特性和功能,抽象工厂模式有多个抽象产品。
4. 具体产品(ConcreteProduct):实现了抽象产品角色所定义的接口,由具体工厂来创建,它同具体工厂之间是多对一的关系。
3.3抽象工厂模式代码示例
首先我们去定义抽象产品
比如
* @Description 车接口 */ public interface Car { void startCar(); void stopCar(); void washCar(); }
* @Description 车载音响类 */ public interface CarAudio { void startCarAudio(); void stopCarAudio(); }
提供具体的产品
* @Description 奥迪车 */ public class AodiCar implements Car { @Override public void startCar() { System.out.println("启动奥迪车"); } @Override public void stopCar() { System.out.println("关闭奥迪车"); } @Override public void washCar() { System.out.println("洗奥迪车"); } }
* @Description 奥迪车载音响 */ public class AodiCarAudio implements CarAudio{ @Override public void startCarAudio() { System.out.println("开启奥迪车载音响"); } @Override public void stopCarAudio() { System.out.println("关闭奥迪车载音响"); } }
* @Description 宝马车 */ public class BaomaCar implements Car{ @Override public void startCar() { System.out.println("开启宝马"); } @Override public void stopCar() { System.out.println("停下宝马"); } @Override public void washCar() { System.out.println("洗宝马"); } }
* @Description 宝马车载音响 */ public class BaomaCarAudio implements CarAudio{ @Override public void startCarAudio() { System.out.println("打开宝马车载音响"); } @Override public void stopCarAudio() { System.out.println("关闭宝马车载音响"); } }
提供抽象的工厂
* @Description 产品工厂接口 */ public interface ProductFactory { Car ProductCar(); CarAudio ProductCarAudio(); }
提供具体的工厂
* @Description 宝马工厂 */ public class BaomaFactory implements ProductFactory{ @Override public Car ProductCar() { return new BaomaCar(); } @Override public CarAudio ProductCarAudio() { return new BaomaCarAudio(); } }
* @Description aodi工厂 */ public class AodiFactory implements ProductFactory{ @Override public Car ProductCar() { return new AodiCar(); } @Override public CarAudio ProductCarAudio() { return new AodiCarAudio(); } }
客户测试类
* @Description 消费者类 */ public class Customer { public static void main(String[] args) { System.out.println("--------奥迪系列---------"); //获得奥迪工厂 AodiFactory aodiFactory = new AodiFactory(); Car car = aodiFactory.ProductCar(); CarAudio carAudio = aodiFactory.ProductCarAudio(); car.startCar(); car.stopCar(); carAudio.startCarAudio(); System.out.println("--------宝马系列---------"); BaomaFactory baomaFactory = new BaomaFactory(); Car carBaoma = baomaFactory.ProductCar(); CarAudio carAudioBaoma = baomaFactory.ProductCarAudio(); carBaoma.stopCar(); carBaoma.washCar(); carAudioBaoma.startCarAudio(); } }
输出结果
--------奥迪系列---------
启动奥迪车
关闭奥迪车
开启奥迪车载音响
--------宝马系列---------
停下宝马
洗宝马
打开宝马车载音响
idea中类图关系
如果我们要新增产品,需在总工厂去添加方法,而且其他的类也会修改,印证了我们之前写到的缺点,
总结一下:
抽象工厂模式就是围绕一个超级工厂创建其他工厂,该超级工厂又称为其他工厂的工厂
四、小结
工厂模式的核心本质
实例化对象不使用new,用工厂方法代替
将选择实现类,创建对象时统一管理和控制,从而将调用者跟我们的实现类解耦
简单工厂模式:用来生产同一等级结构中的任意产品(对于增加新的产品,需要覆盖已有代码)
工厂方法模式:用来生产同一等级结构中的固定产品(支持增加任意产品)
抽象工厂模式:围绕一个超级工厂创建其他工厂,该超级工厂又称为其他工厂的工厂
本篇文章就到这里了,希望能够给你带来帮助,也希望您能够多多关注脚本之家的更多内容!