设计模式-工厂方法&抽象工厂模式
在进行整理工厂方法模式之前,首先来整理一下六大设计原则中的依赖倒置原则
。
先来看一个例子:
这里有一个PizzaStore,也就是一个Pizza工坊,由于Pizza工坊要开下去,就一定要依赖一些相关的Pizza实体,所以此时的PizzaStore
是依赖于各个Pizza的子类
的。
如果此时,我们把这些一个一个的Pizza进行整理,将这些Pizza类都整理到Pizza类的麾下,这样就能够创建一个Pizza接口,让所有类型的Pizza实体都去依赖于这个Pizza实体,也就是所有的Pizza类都是Pizza接口的实现类。经过一系列的处理,原来的PizzaStore和各个Pizza类之间的关系就变成了下面的这种关系。
可以看到,原来的PizzaStore依赖于各个Pizza的子类变成了PizzaStore仅仅依赖于Pizza这个类(接口)就够了。在这里我觉得Pizza是个抽象类或者是一个接口都可以。然后各个子类可以是继承于Pizza类或者是实现了Pizza接口。由于各个子类是继承自Pizza类或者是Pizza接口的实现类,所以各个子类又是依赖于Pizza的。
简单提一下在OO设计中避免违反依赖倒置原则的几个小tips:
-
变量不可以持有具体类的引用(说人话也就是
不要直接去new某个具体类
) -
不要让类派生自具体类(这里的想法是
尽量继承抽象类或者说是实现对应的接口
) -
不要覆盖基类中已经实现的方法(也就是说
如果覆盖基类已经实现的方法,那么基类就不适合做被抽象的对象
)
综上所述,依赖倒置原则的简单描述就是要依赖抽象,不要依赖具体类
。依赖倒置原则中的倒置
指的是和一般的OO设计原则的思考方式完全相反
。
接着进行工厂方法模式的整理。
简单描述:定义一个创建接口的对象,但由子类
决定
要实例化的类是哪一个。工厂方法模式让类的实例化推迟到了子类。所属类型:创建型模式
实现原则:将实现推迟到子类,也就是通过接口或者继承来实现解耦
实现方法:通过继承的方式或者是通过实现接口的方法来实现具体的类
在对工厂方法的简单描述当中,决定
并不是值模式允许子类本身在运行时做决定,而是指在编写创建者类时,不需要知道实际创建的产品是哪一个
。
工厂方法的例子如下所示:
在这个例子当中,对Product
和Creator
进行了考虑。首先对于Product
来说,Product
是所有的ConcreteProduct
的共同接口,Creator
和ConcreteCreator
的关系也是一样,ConcreteCreator
是Creator
的具体实现类。
简述简单工厂和工厂方法:
简单工厂
虽然不是一种模式,但是一种常用的思想。简单工厂
把全部的事情在同一个地方处理完,然后工厂方法
创建一个框架,让子类决定具体如何实现。举个PizzaStore的例子:在工厂方法
中,orderPizza()方法提供了一般的框架,来创建pizza。可以通过继承PizzaStore的方法来决定实际创造出来的pizza是什么。而简单工厂
的做法可以将对象的创建封装起来。但是简单工厂不具备工厂方法的弹性
,因为简单工厂不能变更正在创建的产品
。简述两者的差别在于:工厂方法比简单工厂更具弹性,可以更好地应对未来的扩展
。
工厂方法
用来处理对象的创建,并将这样的行为封装在子类中。这样程序中关于超类的代码
和子类创建对象创建代码
就解耦了。
abstract Product factorymethod(String type)
-
abstract
:工厂方法是抽象的,所以依赖于子类来处理对象的创建 -
Product
:工厂方法必须返回一个产品,超类中定义的方法,通常使用工厂方法的返回值 -
factorymethod
:工厂方法将客户(批萨店铺例子的orderPizza())
和实际创建具体产品的代码
分割开来 -
String type
:可以对该方法传递参数,也可以不传递参数
工厂方法模式
通过让子类决定该创建的对象是什么
,来达到将对象创建的过程封装
的目的。
拿制作Pizza来进行举例:
其中,PizzaStore
是一个抽象的创建者类,它定义相关的抽象工厂方法,让其子类来进行实现。上图中,定义createPizza()
为抽象方法,通过PizzaStore
的子类NYPizzaStore
和ChicagoPizzaStore
来实现具体的实体类。这是对于创建者(Creator)而言的。对于产品类Pizza
来说,Pizza
类也有很多种类的具体实现。
抽象工厂模式
简单描述:提供一个接口,用于创建相关或依赖对象的家族,而不需要明确指定具体类。也可以说【抽象工厂模式是
其他工厂的工厂
】所属类型:创建型模式
实现原则:将实现推迟到子类,也就是通过接口或者继承来实现解耦
实现方法:通过继承的方式或者是通过实现接口的方法来实现具体的类
抽象工厂的任务是定义一个负责创建一组产品的接口
。抽象工厂
允许客户使用抽象的接口来创建一组相关的产品,而不需要知道实际产出的具体产品是什么
,从而实现客户
和具体的产品
之间的解耦
。
对于抽象工厂
而言,首先抽象工厂定义相关的接口,继承/实现他的所有具体工厂都要实现抽象工厂中定义的相关接口
。而所有的具体工厂实现不同的产品家族,如果此时要创建一个产品,客户只需要使用其中的一个工厂并且完全不需要实例化任何产品对象。
抽象产品
也是如此,每一个具体的工厂都能够生产一整组的产品。
整理一下工厂方法
和抽象工厂
这两种模式:
工厂方法
和抽象工厂
都能够进行解耦
。
抽象工厂
的方法经常以工厂方法
的方式实现。
工厂方法
就是通过子类来创建对象,这样客户只需要知道他们所使用的抽象类型就可以了,而由子类来负责决定具体类型。
抽象工厂
提供一个用来创建一个产品家族的抽象类型,这个类型的子类定义了产品被产生的方法。也就是可以把一群相关的产品集合起来
。
工厂方法和抽象工厂都是使应用程序解耦
,降低对特定实现的依赖
。
再来粘两张图来整理下工厂方法
和抽象工厂
。
靠上的图描述的是工厂方法
的例子,靠下的图描述的是抽象工厂
的例子。
最后再来进行整理一下:
工厂方法模式
:定义一个创建对象的接口,但由于子类决定要实例化的类是哪一个。工厂方法让类把实例化推迟到子类。
抽象工厂模式
:提供一个接口,用于创建相关或依赖对象家族,而不需要明确指定具体类
要点整理:
-
-
简单工厂
虽然不是真正的设计模式,但仍不失为一个简单的方法,可以将客户程序从具体类解耦。 -
工厂方法
使用继承
,把对象的创建委托给子类,子类实现工厂方法来创建对象 -
抽象工厂
使用对象组合
,对象的创建被实现在工厂接口所暴露出来的方法中 -
所有工厂模式都通过减少应用程序和具体类之间的依赖促进松耦合
-
工厂方法
允许类将实例化延迟到子类进行 -
抽象工厂
创建相关的对象家族,而不需要依赖它们的具体类 -
依赖倒置原则,指导我们避免依赖具体类型,而要尽量依赖抽象
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 如何编写易于单元测试的代码
· 10年+ .NET Coder 心语,封装的思维:从隐藏、稳定开始理解其本质意义
· .NET Core 中如何实现缓存的预热?
· 从 HTTP 原因短语缺失研究 HTTP/2 和 HTTP/3 的设计差异
· AI与.NET技术实操系列:向量存储与相似性搜索在 .NET 中的实现
· 10年+ .NET Coder 心语 ── 封装的思维:从隐藏、稳定开始理解其本质意义
· 地球OL攻略 —— 某应届生求职总结
· 周边上新:园子的第一款马克杯温暖上架
· 提示词工程——AI应用必不可少的技术
· Open-Sora 2.0 重磅开源!