3.3 FACTORY METHOD(工厂方法) — 对象创建型模式

时间:2021-6-3 作者:qvyue
1.意图

定义一个用于创建对象的接口,让子类决定实例化哪一个类。Factory Method使一个类的实例化延迟到其子类。

2.别名

虚构造器(Virtual Constructor)

3.动机

框架使用抽象类定义和维护对象之间的关系。这些对象的创建通常也由框架负责。
考虑这样一个应用框架,它可以向用户显示多个文档。在这个框架中,两个主要的抽象是类Application和Document。这两个类是抽象的,客户必须通过它们的子类来做与具体应用相关的实现。例如,为创建一个绘图应用,我们定义类DrawingApplication和DrawingDocument。Application类负责管理Document并根据需要创建它们——例如,当用户从菜单中选择Open或New的时候。

因为被实例化的特定Document子类是与特定应用相关的,所以Application类不可能预测到哪个Document子类将被实例化——Application类仅知道一个新的文档何时被创建,而不知道哪一种Document将被创建。这就产生了一个尴尬的局面:框架必须实例化类,但是它只知道不能被实例化的抽象类。

Factory Method模式提供了一个解决方案。它封装了哪一个Document子类将被创建的信息并将这些信息从该框架中分离出来,如图:

3.3 FACTORY METHOD(工厂方法) — 对象创建型模式
image.png

Application的子类重定义Application的抽象操作CreateDocument以返回适当的Document子类对象。一旦一个Application子类实例化以后,它就可以实例化与应用相关的文档,而无需知道这些文档的类。我们称CreateDocument是一个工厂方法,因为它负责“生产”一个对象。

4 适用性

在下列情况下可以使用Factory Method模式:

  • 当一个类不知道它所必须创建的对象的类的时候;
  • 当一个类希望由它的子类来指定它所创建的对象的时候;
  • 当类将创建对象的职责委托给多个帮助子类中的某一个,并且你希望将哪一个帮助子类的代理者这一信息局部化的时候。
5.结构
3.3 FACTORY METHOD(工厂方法) — 对象创建型模式
image.png
6 参与者
- Product(Document)——定义工厂方法所创建的对象的接口;
- ConcreteProduct(MyDocument)——实现Product接口
- Creator(Application)

——声明工厂方法,该方法返回一个Product类型的对象。Creator也可以定义一个工厂方法的缺省实现,它返回了一个缺省的ConcreteProduct对象;
——可以调用工厂方法以创建一个Product对象;
– ConcreteCreator(MyApplication)——重定义工厂方法以返回一个ConcreteProduct实例

7 协作

creator依赖于它的子类来定义工厂方法,所以它返回一个适当的ConcreteProduct实例。

8 效果

工厂方法不再将与应用有关的类绑定到你的代码中,代码仅处理Product接口;因此它可以与用户定义的任何ConcreteProduct类一起使用。
工厂方法的一个潜在缺点在于客户可能仅仅为了创建一个特定的 ConcreteProduct对象,就不得不创建Creator的子类。当Creator子类不必需时,客户现在必然要处理类演化的其他方面;但是当客户无论如何必须创建 Creator的子类时,创建子类也是可行的。
另外两种效果:
– 为子类提供挂钩(hook)
– 连接平行的类层次

3.3 FACTORY METHOD(工厂方法) — 对象创建型模式
image.png
9.实现

当应用Factory Method模式时要考虑下面一些问题:

    1. 主要有两种不同的情况
      • Creator类是一个抽象类并且不提供它所声明的工厂方法的实现
      • Creator是一个具体的类而且为工厂方法提供一个缺省的实现
  • 2.参数化工厂方法
    该模式的另一种情况使得工厂方法可以创建多种产品。工厂方法采用一个标识要被创建的对象种类的参数。工厂方法创建的所有对象将共享Product接口。在Document的例子中,Application可能支持不同种类的Document。
  • 3.特定语言的变化和问题
  • 4.使用模板以避免创建子类
  • 5.命名约定 使用命名约定是一个好习惯,它可以清楚地说明你正在使用工厂方法。例如,Macintosh的应用框架MacApp [App89]总是声明那些定义为工厂方法的抽象操作为 Class*
    DoMakeClass( ),此处Class是Product类。
10 代码示例

github地址

声明:本文内容由互联网用户自发贡献自行上传,本网站不拥有所有权,未作人工编辑处理,也不承担相关法律责任。如果您发现有涉嫌版权的内容,欢迎发送邮件至:qvyue@qq.com 进行举报,并提供相关证据,工作人员会在5个工作日内联系你,一经查实,本站将立刻删除涉嫌侵权内容。