工厂模式
工厂模式可简单的分为三类:简单工厂,工厂方法,抽象工厂
简单工厂模式
定义
简单工厂模式是属于创建型模式,又叫做静态工厂方法(Static Factory Method)模式,但不属于23种GOF设计模式之一。简单工厂模式是由一个工厂对象决定创建出哪一种产品类的实例。简单工厂模式是工厂模式家族中最简单实用的模式,可以理解为是不同工厂模式的一个特殊实现
角色
-
工厂类角色:这是本模式的核心,含有一定的商业逻辑和判断逻辑,根据逻辑不同,产生具体的工厂产品
-
抽象产品角色:它一般是具体产品继承的父类或者实现的接口。由接口或者抽象类来实现
-
具体产品角色:工厂类所创建的对象就是此角色的实例。在oc中由一个具体类实现
应用场景
-
编译时无法确定预期要创建的对象类
-
类想让子类决定运行时创建什么
-
类有若干的辅助子类,而你想将返回那个子类这一信息局部化
简化理解
简单工厂模式:专门定义一个类来创建其他类的实例,被创建的实例常常具有共同的父类,实际上就是由一个工厂类,根据传入的参数,动态的决定创建哪个产品的实例
优缺点
-
优点:客户端调用简单明了,不需要关注太多的逻辑
-
缺点:也正是所谓的优点,导致了工厂类中揉杂了太多的业务逻辑,工厂类却违反了开闭原则,因为每增加一个产品,工厂类都需要进行逻辑修改和判断,导致耦合度太高
工厂方法
定义
定义创建对象的接口,让子类决定实例化哪一个类。工厂方法使得一个类的实例化延迟到其子类。
上面提过了简单工厂模式中的工厂类揉杂了太多了业务逻辑,耦合度太高了,比如又新增了一种具体产品角色,那么我们还需要在工厂类里增加判断,然后在根据判断去创建新增加的具体产品角色
角色
- 抽象工厂:(iOS是接口(协议),java是抽象类),工厂标准
- 具体工厂:遵守工厂标准
- 抽象产品:(接口(协议),抽象类)
- 具体产品
简单理解
抽象产品角色(可以是接口(协议中的接口)或者抽象类)定义里工厂方法创建的对象的接口和产品的共性,
在工厂方法中,核心的工厂类角色不再去负责创建具体产品,而是由它的子类去做,这个工厂类角色,仅仅负责给出具体工厂必须实现的接口,而不接触哪一个产品类被实例化这种细节
与直接创建新的具体产品相比,工厂方法模式让客户程序可以要求由工厂方法创建的对象拥有一组共同的行为。这样往类层次结构中引入新的具体产品时,并不需要修改客户端代码,因为返回的任何具体对象的接口都跟客户端一直在用的从前的接口相同。从结构图也可以看到,工厂方法模式中的工厂类与产品类往往具有平行的等级结构,它们之间一一对应。
与简单工厂模式的对比
在简单工厂模式中,由工厂类根据参数负责创建具体的产品;而在工厂方法模式中,工厂类只定义了一个创建产品的抽象接口,创建具体产品的工作由具体的工厂来实现。如果需要增加其他类型的图形绘制,那么使用简单工厂模式实现的话,首先需要增加一个其他图形绘制的类,然后修改工厂类,在里面加分支语句来判断;使用工厂方法模式实现的话,不仅需要增加图形绘制类,还需要增加具体工厂类。看到这里,可能大家会感觉到,工厂方法模式不但没有减少难度,反而增加了一些类和复杂度。这样来看,是不是没有必要使用工厂方法模式?咱们再回顾一下开篇介绍的六大设计原则,有一个原则是开放-关闭原则,简单工厂模式不仅对扩展开放,而且对修改也开放,开放-关闭原则。工厂方法模式是简单工厂模式的进一步抽象,它保持了简单工厂模式的优点(去除了客户端与具体产品的依赖),而且克服了它的缺点开放-关闭原则。它的缺点是每增加一个产品,就需要加一个产品工厂的类,增加了额外的开发工作量
抽象工厂模式
定义
在前面两章中,分别介绍了简单工厂模式和工厂方法模式,我们知道简单工厂模式的优点是去除了客户端与具体产品的依赖,缺点是违反了开放-关闭原则;工厂方法模式克服了简单工厂模式的缺点,将产品的创建工作放到具体的工厂类,每个工厂类负责生成一个产品。但是在实际应用中,一个工厂类只创建单个产品的情况很少,一般一个工厂类会负责创建一系列相关的产品,如果我们要设计这样的系统,工厂方法模式显然不能满足应用的需求,本章要介绍的抽象工厂模式,可以很好地解决一系列产品创建的问题
简单理解
供一个创建一系列相关或相互依赖对象的接口,而无需指定它们具体的类
我觉得跟工厂模式一样,只是不止一个抽象产品的而已
先对的几个角色进行说明:
- AbstractFactory:抽象工厂接口,里面应该包含所有产品创建的抽象方法;
- ConcreteFactory1和ConcreteFactory2:具体的工厂,创建具有特定实现的产品对象;
- AbstractProductA和AbstractProductB:抽象产品,它们可能有多种不同的实现方式;
- ProductA1、ProductA2、ProductB1和ProductB2:具体的产品,是抽象产品的具体实现。
从结构图中可以看到,抽象工厂方法最大的好处是能够很方便的变换产品系列(例如id<AbstractFactory> factory =[ [ConcreteFactory1 alloc] init],只需要将ConcreteFactory1换成ConcreteFactory2,就可以创建ProductA2和ProductB2)。另外,抽象工厂方法让具体的创建实例过程与客户端分离,客户端是通过它们的抽象接口操作实例,产品的具体类名也被具体工厂的实现分离,不会出现在客户代码中(例如id<AbstractProductA> product = [factory createProductA],客户端根本不知道具体的类名是ProductA1还是ProductA2)。
但是,抽象工厂方法也是存在缺点的,比如说现在我们要增加一个新的产品,首先,我们需要增加三个类:AbstractProductC、ProductC1、ProductC2;另外,我们还需要更改三个类:AbstractFactory、ConcreteFactory1、ConcreteFactory2,这样,很明显是违背开放-关闭原则。这也是可以理解的,没有任何一个设计模式是完美没有瑕疵的,这就好比世界上没有打不败的武功一样。我们可以做的就是在实际的需求中,尽可能的将变化点进行隔离,以达到变化发生的时候,对整个系统的影响最小,变化所带来的变更和成本最低
``
网友评论