终于学习完了工厂模式啦,今天写篇博客总结一下。
一、引言
工厂模式是啥?有什么用?怎么实现?,接下来一一解答。
1. 工厂模式是什么东西?
工厂模式就像当于一个奶茶店,你需要什么,告诉他一声,人家就给你整出来,而不用自己去做出来。
例如:老王想要辆奥迪,这个时候有2种选择,一是自己造出来(java里面称为new),第二种就是告诉4S店(工厂),然后交钱提车走人。
第二种就是工厂模式,你需要什么,告诉人家一声,别人就会给你造出来。
2. 有什么用?
工厂模式意在解耦,就是在程序模块中减少每个模块的紧密关系,做到低耦合,让代码维护起来更加方便,轻松。
3. 怎么实现?
怎么实现呢?跟单例模式类似,工厂模式一共有3种实现方式:
- 简单工厂
- 工厂方法
- 抽象工厂
接下来对这几种实现方式一一阐述。
二、实现工厂模式
1、简单工厂
直接上类图:
类图清晰简单易懂,就是奥迪,奔驰,宝马,实现了一个名为Car的接口。
一个工厂依赖这三种汽车。
下面是实现代码:
下面是Car,接口和奥迪,宝马,奔驰实现类
//Car接口
public interface Car {
}
//奥迪
class Audi implements Car{
}
//宝马
class BMW implements Car{
}
//奔驰
class Benz implements Car{
}
下面是汽车工厂和Main方法
//汽车工厂
public class CarFactory {
//获取汽车的方法
public static Car getCar(String name){
if (name.equals("奥迪")){
return new Audi();
}
if (name.equals("宝马")){
return new BMW();
}
if (name.equals("奔驰")){
return new Benz();
}else {
return null;
}
}
//Main方法
public static void main(String[] args) {
//告诉工厂要什么车型,它就给你造什么车
Car 奥迪 = CarFactory.getCar("奥迪");
Car 宝马 = CarFactory.getCar("宝马");
Car 奔驰 = CarFactory.getCar("奔驰");
}
}
主要就是汽车工厂中的getCar()方法,你给它传奥迪,他就造奥迪,传宝马就造宝马。以上就是简单工厂模式,到这里应该很好理解,也很简单。
但是这样的工厂有个小问题:没有遵守开闭原则 忘记的兄弟点这里,就是违反了对提供方拓展开放,对使用方修改关闭。
例如:老王突然有钱了,想要买一辆劳斯莱斯,这时候告诉汽车工厂,汽车工厂怎么做?势必修改源代码,改完如下:
//劳斯莱斯
class RollsRoyce implements Car{
}
为了拓展车型,增加劳斯莱斯类没有任何问题,但是看如下:
//获取汽车的方法
public static Car getCar(String name){
if (name.equals("奥迪")){
return new Audi();
}
if (name.equals("宝马")){
return new BMW();
}
if (name.equals("奔驰")){
return new Benz();
}if (name.equals("劳斯莱斯")){
return new RollsRoyce();
}
else {
return null;
}
}
增加了一个if条件,这就很有问题了,严重违反开闭原则,修改了原有的代码,所以我们提出了第二种工厂:工厂方法模式
2、工厂方法
工厂方法模式可以任意增加车型,而且每次都不需要修改原来的代码,遵守开闭原则,类图如下:
看起来也应该很简单,就是把原本的一个工厂拆分,现在每种工厂实现工厂接口并且只负责生产它对应的汽车(奥迪工厂生成奥迪汽车)
现在如果老王想要一辆宾利,只需要新建一个宾利工厂实现汽车工厂接口即可,再也不用修改原来的代码了。
实现代码如下:
//汽车工厂接口
public interface CarFacory {
public Car getCar();
}
//奥迪工厂
class AudiFactory implements CarFacory{
public Car getCar() {
return new Audi();
}
}
//宝马工厂
class BMWFactory implements CarFacory{
public Car getCar() {
return new BMW();
}
}
//奔驰工厂
class BenzFactory implements CarFacory{
public Car getCar() {
return new Benz();
}
}
//莱斯老师工厂
class RollsRoyceFactory implements CarFacory{
public Car getCar() {
return new RollsRoyce();
}
}
以下是各种车型:
//Car接口
public interface Car {
}
//奥迪
class Audi implements Car {
}
//宝马
class BMW implements Car {
}
//奔驰
class Benz implements Car {
}
//劳斯莱斯
class RollsRoyce implements Car {
}
以上可以看出工厂方法模式可以很好解决添加车型时修改原本代码的工作。
但是麻烦又来了,由于疫情严重,各大工厂都准备生产口罩来满足市场需要,现在工厂不止生产汽车了,还生产口罩。这下工厂方法显然又不行了,于是出先了抽象工厂。
3、抽象工厂(比较难理解,简单工厂和工厂方法觉得吃力的话先不要看)
按照惯例,直接上类图:
每个工厂继承一个抽象类(抽象工厂),一共有2个方法,getCar(获取汽车),getMask(获取口罩)。然后每个工厂依赖于自己品牌的汽车和口罩,
例如:奥迪工厂含有奥迪汽车和奥迪口罩;宝马工厂含有宝马汽车和宝马口罩。
实现代码如下:
下面是汽车类:
//Car接口
public interface Car {
}
//奥迪
class Audi implements Car {
}
//宝马
class BMW implements Car {
}
//奔驰
class Benz implements Car {
}
下面是口罩类:
//口罩接口
public interface Mark {
}
//奥迪口罩
class AudiMark implements Mark{
}
//宝马口罩
class BMWMark implements Mark{
}
//奔驰口罩
class BenzMark implements Mark{
}
下面是工厂:
//抽象工厂
public abstract class AbsFactory {
public abstract Car getCar();
public abstract Mark getMark();
}
//奥迪工厂
class AudiFactory extends AbsFactory{
public Car getCar() {
return new Audi();
}
public Mark getMark() {
return new AudiMark();
}
}
//宝马工厂
class BMWFactory extends AbsFactory{
public Car getCar() {
return new BMW();
}
public Mark getMark() {
return new BMWMark();
}
}
//奔驰工厂
class BenzFactory extends AbsFactory{
public Car getCar() {
return new Benz();
}
public Mark getMark() {
return new BenzMark();
}
}
三、总结
三种工厂实现模式没有好坏之分,最常用的就是简单工厂,工厂方法和抽象工厂要分具体实际情况来使用。
总体来说工厂模式还是较为简单的模式,只要动手写写代码,画画类图,都可以理解。
实在不理解可以看视频教学:
秦疆老师的工厂方法
秦疆老师的抽象工厂
创作不易,还望各位兄弟姐妹们点点赞,谢谢大家!