工厂模式有三类,分别是简单工厂模式,工厂方法模式和抽象工厂模式
一,简单工厂模式
课本上给出的例子是制造一个计算器,我们知道一个计算器需要输入进行运算的两个数,还要给出进行什么样的运算,如果使用单纯的结构化编程则会导致大量的代码重复,导致难以维护
那么我们可以这样来考虑,两个数据是固定的,那我们我们只需要把加减乘除类分别包装起来就可以,又因为加减乘除类有很多的代码是重叠的,我们可以定义一个抽象类来进行运算
我们的客户端在调用的时候,输入运算符然后传入到抽象类中,抽象类根据这传入的符号用一个switch判断就可以建立一个相应的类,然后的到结果
这样做的一个缺点就是客户端传入运算符还需要再进行一次判断,如果想要省去这一步,我们可以进行再XML文件中进行匹配
我们写的那个接口就是用来隔离具体的实现,目标就是不要让客户端知道封装体内部的具体实现。简单工厂的位置就是位于封装体内所以简单工厂知道具体类的实现是没有关系的
对于客户端来说,只是知道了接口和简单工厂
优点:
-
工厂类含有必要的逻辑判断,可以决定在什么时候创建哪一个产品类的实例
-
客户端可以免除直接创建产品对象的责任,仅仅消费产品,简单工厂模式通过这种做法实现类对责任的分割
缺点:
-
当产品有复杂的多层等级结构的时候,工厂类只有自己,以不变应万变就是模式的缺点。因为工厂类中集中了所有产品的创建逻辑,一旦不能正常运行,整个系统都要受到影响
-
系统扩展困难,一旦添加新产品就不得不修改工厂的逻辑,有可能造成工厂的逻辑过于复杂
-
另外,简单工厂模式通常使用静态工厂方法,这使得方法由子类继承,而工厂角色是不能继承别人的
本质: 选择实现
应用场景:
-
如果想要完全封装隔离具体实现,让外部只能通过接口来操作封装体,则可以选用简单工厂。让客户端通过工厂来获取相应的接口,而无需关心具体的实现
-
如果想要把对外创建对象的职责集中管理和控制,可以选择简单工厂
二,工厂方法模式
简单工厂模式中, 优点是工厂类中包含了必要的逻辑判断,根据客户端的选择条件动态实例化相关的类,对于客户端来说,去除了与具体产品的依赖
缺点就是在某种程度上违背了开放--封闭原则,对于工厂类过于依赖
而在工厂方法模式中,定义了一个创建产品对象的工厂接口,将实际创建的工作推迟到了子类中。
在工厂方法模式中,核心的工厂类不再负责所有产品的创建,而是将具体创建工作交给子类去做。这个核心类仅仅负责给出具体工厂必须实现的接口,而不接触哪一个产品类被实例化这种细节。这样一来就可以在不改变工厂角色的情况下引进新的产品
Creator(抽象工厂角色):
工厂方法模式的核心,与应用程序无关,任何在模式中创建的对象的工厂类必须实现这个接口
BulbCreator,TubeCreator(具体工厂角色)
Light(抽象产品角色)
BuldLight,TubeLight(具体产品角色)
具体的代码:
抽象工厂角色:
具体工厂角色:
抽象产品角色:
具体产品角色:
客户端在调用的时候:
用具体的工厂类来实例化工厂类
实例,在实际的公司中不同数据格式之间需要进行转换,比如文本格式,数据库备份格式,Excel,xml格式
具体的代码:
之前写的找不到了,和上一个实例差不多,也就是根据具体的需求实例化不同的具体工厂类
| 结构上 | 核心 |
简单工厂模式 | 基本相似 | 具体类 |
工厂方法模式 | 基本相似 | 抽象工厂类 |
别名:多态性工厂模式,因为具体工厂类都有共同的接口,或者有共同的抽象父类
优点:
当系统扩展需要添加新的产品对象的时候,只需要添加一个个具体对象以及一个具体工厂对象,原有的工厂对象不需要进行任何修改,也不需要(尽量小的)修改客户端,符合“开-闭”原则
缺点:
具体的产品对象与工厂方法的耦合性
工厂方法是要创建产品对象的,也就是需要选择具体的产品对象,并且创建他们的实例。具体的产品对象与工厂方法是耦合的
什么时候调用:
-
如果一个类需要创建某个接口的对象,但是又不知道具体的实现,可以把创建对象的工作延迟到子类中
-
如果一个类本身就希望由他的子类来创建所需的对象的时候,应该使用工厂方法模式
本质:
延迟到子类中来选择实现
三,抽象工厂模式
我们首先给出一个例子就是更换数据库的例子
我们知道连接数据库的时候,有时候需要我们把一个数据库更换成为另一个数据库,那我们就需要更改数据库名,数据库所在的位置和数据库密码都需要更改,这样一来就比较麻烦,我们可以这样来考虑实现,通过工厂方法模式
这样需要用到哪一个数据库
在IFactory实例化的时候实例化成为哪一个就可以
但是,当数据库中不仅有User表还有其他表的时候,比如还有Department表的时候,我们该怎么办呢?
通过再建立一个抽象表接口,然后在数据库工厂中再加上这个创建的方法
具体代码:
抽象工厂类:
具体实现的工厂类:
产品类接口:
具体产品类:
User的具体实现和Department的实现差不多,也就是建立一个接口和分别的实现
客户端的调用:
以上就是抽象工厂模式,抽象工厂模式是所有形态的工厂模式中最为抽象和最具一般性的一种形态
定义:提供一个创建一系列相关或者相互依赖的接口,而无需指定他们具体的类
这个地方还需要知道一个概念就是产品组
产品组就是几个不同的等级结构共同构成
那么抽象工厂是指一个工厂等级结构可以创建出分属于不同产品等级结构的一个产品族中的所有对象。
在什么情形下使用:
-
希望一个系统不应当依赖于产品类实例如何被创建,组合和表达的细节时
-
一个系统中有多于一个的产品组,而系统只消费其中某一个产品组
抽象工厂模式 | 工厂模式 |
为创建一组(有多类)相关或依赖的对象提供创建接口 | 为一类对象提供创建接口 |
抽象工厂模式以一种倾斜的方式支持增加新的产品,它为新产品组的增加提供方便,而不能为新的产品等级结构增加提供这样的方便
本质:
选择产品族的实现