简单工厂模式(Simple Factory Pattern)

定义

又称静态工厂方法(Static Factory Method)模式,属于类创建型模式。在简单工厂模式中,可以根据参数的不同返回不同类的实例。简单工厂模式专门定义一个类来负责创建其他类的实例,被创建的实例通常都具有共同的父类。

图解

简单工厂

一共三个角色:

  • 工厂角色(Factory):负责实现创建所有实例的内部逻辑;
  • 抽象产品角色(Product):具体对象的父类,负责描述所有实例共有的公共接口;
  • 具体产品角色(ConcreteProduct):最终的创建目标,所有创建的对象都充当这个角色某个具体类的实例。

特点

  • 将对象的创建和对象本身业务处理分离,降低系统耦合度;
  • 工厂方法是静态方法,使用起来很方便,可以直接通过类名调用,只需要传入一个简单的参数;
  • 最大的问题在于对于工厂类的职责相对过重,增加新的产品需要修改工厂类的判断逻辑。

优点

  • 含有必要的判断逻辑,可以决定在什么时候创建哪一个产品类的实例,客户端免除直接创建产品对象的责任;
  • 客户端只需要知道产品类的参数即可,减少使用者的对复杂类名的记忆量;
  • 引入配置文件,可以在不修改任何客户端代码的情况下更换和增加新的具体产品类。

缺点

  • 工厂类集中了所有产品创建逻辑,一旦不能工作,整个系统都要受到影响;
  • 使用简单工厂模式会增加系统中的类的个数,
  • 系统扩展困难,一旦添加新产品就不得不修改工厂逻辑,不利于系统的扩展与维护;
  • 由于使用了静态工厂方法,造成工厂角色无法形成基于继承的等级结构。

我该什么时候使用?

  • 工厂类负责创建的对象比较少;
  • 客户端只知道传入工厂类的参数,对如何创建对象不关心,只需要知道类型对应参数。

工厂方法模式(Factory Method Pattern)

定义

又称为工厂模式,也叫虚拟构造器(Virtual Constructor)模式或多态工厂(Polymorphic Factory)模式,属于类创造型模式。

在工厂方法模式中,工厂父类负责定义创建产品对象的公共接口,而工厂子类则负责生成具体的产品对象。

将产品类的实例化操作延迟到工厂子类中完成。

图解

工厂方法

一共四个角色:

  • Product:抽象产品
  • ConcreteProduct:具体产品
  • Factory:抽象工厂
  • ConcreteFactory:具体工厂

特点

是简单工厂的进一步抽象和推广。由于使用了面向对象的多态性,工厂方法模式保持了简单工厂模式的优点,克服了他的缺点。

所有产品的创建交给了子类去做,核心类仅仅负责给出具体工厂必须实现的接口,而不负责哪一个产品类被实例化。

使得工厂方法模式可以允许系统在不修改工厂角色的情况下引进新产品。

1
2
3
4
5
6
7
8
9
10

class Solution
{
public void FcTest()
{
Factory fc = new ConcerteFactory(); // 选择工厂
Product prod = fc.factoryMethod(); // 创建产品-
prod.use();
}
}

优点

  • 工厂方法用来创建客户所需要的产品,同时还向客户隐藏了哪种具体类将被实例化这一细节。只需要知道产品所需的工厂继续ing;
  • 基于工厂角色和产品角色的多态性设计是工厂方法模式的关键。所有具体工厂类都具有同一个抽象父类;
  • 系统加入新产品时,无需修改抽象工厂和抽象产品提供的接口,无需修改客户端,也无需修改其他的具体工厂和具体产品。只需要添加一个具体工厂和具体产品就可以了。

缺点

  • 每新增一个产品,就要编写新的具体产品类,还要提供对应的具体工厂类。系统中类的个数成对增加;
  • 客户端代码需要使用抽象层进行定义,增加了系统的抽象性和理解难度,且在实现时可能用到DOM、反射等技术,增加了实现难度。

适用环境

  • 一个类不知道它所需要的对象的类:在工厂方法模式中,客户端不需要知道具体产品类的类名,只需要知道所对应的工厂;
  • 一个类通过其子类来指定创建哪个对象;
  • 将创建对象的任务委托给多个工厂子类中的某一个,客户端在使用时可以无需关心是哪一个工厂子类创建产品子类,需要时再动态指定。

抽象工厂模式(Abstract Factory)

定义

又称Kit模式,属于对象创建型模式。

提供一个创建一系列相关或相互依赖对象的接口,而无需指定它们具体的类。

图解

抽象工厂

包含如下4个角色:

  • AbstractFactory:抽象工厂
  • ConcreteFactory:具体工厂
  • AbstractProduct:抽象产品
  • Product:具体产品

特点

引入了两个概念:

  • 产品等级结构:即产品的继承结构;
  • 产品族:同一工厂生产的,位于不同产品等级结构中的一组产品。

抽象工厂模式面对多个产品等级结构,一个工厂等级结构可以负责多个不同产品等级结构中的产品对象的创建。

例如:

  • 海尔电器工厂生产:海尔电视机、海尔电冰箱等。
  • 其中,海尔电器工厂就是一个具体工厂,它生产的电视机、电冰箱就是海尔产品族。
  • 而海尔电视机属于电视机的产品等级结构,电视机这一抽象产品下还会有海信电视机、索尼电视机等。

优点

  • 抽象工厂模式隔离了具体类的生成,使得客户并不知道什么被创建。可以实现高内聚低耦合的设计目的。
  • 当一个产品族中多个对象一起工作时,抽象工厂模式能够保证客户端始终只使用一个产品族中的对象。

缺点

  • 在添加新的产品对象时,难以扩展抽象工厂来生产新种类的产品,这是因为在抽象工厂角色中规定了所有可能被创建的产品集合,要支持新种类的产品就意味着要对该接口进行扩展,而这将涉及到对抽象工厂角色及其所有子类的修改,显然会带来较大的不便。
  • 开闭原则的倾斜性(增加新的工厂和产品族容易,增加新的产品等级结构麻烦)。

扩展阅读

【Unity与23种设计模式】抽象工厂模式(Abstract Factory)
Unity C# 设计模式(四)抽象工厂模式