context
上次的文章,用简单工厂,解决了生产布局类的问题. 但是,上次的方式针对一个模块是可以的,当模块多了,每个类负责的属性就太多了.这是一个需要重构的点.
准备工作
首先,将类重命名, 比如 原来的:
GUILayoutFactory -> GUILoginLayoutFactory
原来的布局产品名称也是应该修改的,但是就不贴出来了,一个原则就是:不要让类名把你自己弄迷糊了即可.
重构
下面是我工厂模式的结构图,目前工厂只有 Login这一个,项目中有更多,但是没必要都在此列举.
文件说明图
当把图画出来, 很容易看出来, 需要进行重构了. 因为在 GUILoginLayoutFactory
存在着逻辑判断代码,如下:
1 |
|
上面的代码是当时在应用简单工厂的时候,将逻辑下放到工厂中得.现在它存在于我们的 GUILoginLayoutFactory
中,这个工厂还会有同级的兄弟工厂.它们也需要这种判断来生产具体的 layou产品,比如GUIDiaryLayoutFactory
,那么,现在应该采用将这些代码提升到父类的重构手法. GUILoginLayoutFactory
的父类是我们的 “ 总工厂 “ 也就是 GUILayoutFactory
现在 GUILayoutFactory
的头文件代码是:
1 | #import <Foundation/Foundation.h> |
养成好习惯,每次小重构后都进行编译.
客户端调用代码:
1 | - (void)viewDidLoad { |
是的, 调用端需要知晓具体的工厂.比如这里的 GUILoginFactory
才能拿到具体的产品.
对比简单工厂
原来使用简单工厂实现的时候,如果要增加新产品.那么需要:
- 添加具体的产品(Layout类)
- 在工厂类中增加一个分支语句
客户端是无需修改和知道工厂内部的细节的.
现在使用工厂模式,如果要增加新产品:
- 添加具体的产品(Layout类)
- 添加具体产品的工厂类(LayoutFactory类)
- 客户端进行判断和需要知晓新的工厂类
加重了客户端的负担.
总结来说:
简单工厂最大的优点在于工厂类中包含了必要的逻辑判断,根据客户端的选择(或者是其他条件)动态实例化相关的类,对于客户端来说,去除了与具体产品的依赖 .
但是如果添加新产品,要修改工厂类,违背了”开放-封闭原则”
工厂模式让子类工厂决定实例化哪个类.让产品类的实例化延迟到了子工厂.
新增加产品的时候, 整个工厂的体系是没有修改的,只是扩展出一个子类.
工厂模式,客户端需要知晓具体的工厂子类
两者没有好坏, 我们需要根据自己的实际情景来选择模式进行应用.