- 浏览: 62689 次
- 性别:
- 来自: 北京
文章分类
最新评论
1、意图
定义一个用于创建对象的接口,让子类决定实例化哪一个类。Factory Method使一个类的实例化延迟到子类。
2、别名
虚拟构造(Virtual Constructor)
3、动机
框架使用抽象类定义和维护对象之间的关系。这些对象的创建通常也由框架负责。
考虑这样一个框架,它可以向用户展示多个文档。在这个框架中,两个主要的抽象是类Application和Document。这两个类都是抽象的,客户必须通过它们的子类来做与具体应用相关的实现。例如,为创建一个绘图应用,我们定义DrawingApplication和DrawingDocument。Application类负责管理Document并根据需要创建它们----例如,当用户从菜单中选择Open或New的时候。
因为被实例化的特定Document子类是与特定应用相关的,所以Application类不可能预测到哪个Document子类将被实例化----Application类仅知道一个新的文档何时被创建,而不知道哪一个Document将被创建。这就产生了一个尴尬的局面:框架必须实例化类,但是它只知道不能被实例化的抽象类。
Factory Method模式提供了一个解决方案。它封装了哪一个Document子类将被创建的信息并将这些信息从该框架中分离出来。如下图所示
Application的子类重定义Application的抽象操作CreateDocument以返回适当的Document子类对象。一旦一个Application子类实例化以后,它就可以实例化与应用相关的文档,而无需知道这些文档的类。我们称CreateDocument是一个工厂方法(factory method),因为它负责“生产”一个对象。
4、适用性
在下列情况下可以使用Factory Method模式:
当一个类不知道它所创建的对象的类的时候。
当一个类希望由它的子类来指定它所创建的对象的时候。
当类将创建对象的职责委托给多个帮助子类中的某一个,并且你希望将哪一个帮助子类是代理者这一信息局部化的时候。
5、结构
6.参与者
Product(Document)
----定义工厂方法所创建的对象的接口
ConcreteProduct
----实现Product接口
Creator(Application)
----声明工厂方法,该方法返回一个Product类型的对象。Creator也可以定义一个工厂方法的缺省实现,它返回一个缺省的ConcreteProduct。
----可以调用工厂方法创建一个Product对象
ConcreteProduct(MyApplication)
----重定义工厂方法以返回一个ConcreteProduct实例。
7、协作
Creator依赖于它的子类来定义工厂方法,所以它返回一个适当的ConcreteProduct实例。
8、效果
工厂方法不再将与特定应用有关的类绑定到你的代码中。代码仅处理Product接口;因此它可以与用户定义的任何ConcreteProduct类一起使用。
工厂方法的一个潜在缺点在于客户可能仅仅为了创建一个特定的ConcreteProduct对象,就不得不创建Creator的子类。当Creator子类不必需时,客户现在必然要处理类演化的其他方面;但是当客户无论如何必须创建Creator的子类时,创建子类也是可行的。
下面是Factory Method模式的另外两种效果:
1)为子类提供挂钩(hook) 用工厂方法在一个类的内部创建对象通常比直接创建对象更灵活。Factory Method给子类一个挂钩以提供对象的扩展版本。
在Document的例子中,Document类可以定义一个称为CreateFileDialog的工厂方法,该方法为打开一个已有的文档创建默认的文档对话框对象。Document的子类可以重新定义这个工厂方法以定义一个与特定应用相关的文件对话框。在这种情况下,工厂方法就不再抽象了而是提供了一个合理的缺省实现。
2)连接平行的类层次 迄今为止,我们所考虑的例子中,工厂方法并不往往只是被Creator调用,客户可以找到一些有用的工厂方法,尤其在平行类层次的情况下。
当一个类将它的一部分职责委托给一个独立类的时候,就产生了平行类层次。考虑可以被交互操纵的图形;也就是说,它们可以用鼠标进行伸展、移动,或者旋转。实现这样一些交互并不总是那么容易,它通常需要存储和更新在给定时刻记录操纵状态的信息,这个状态仅仅在操纵时需要。因此它不需要被保存在图形对象中。此外,当用户操纵图形时,不同的图形有不同的行为。例如,将直线图形拉长可能会产生一个端点被移动的效果,而伸展正文图形则有可能改变行距。
有了这些限制,最好使用一个独立的Manipulator对象实现交互并保存所需要的任何与特定操纵相关的状态。不同的图形将使用不同的Manipulator子类来处理特定的交互。得到的Manipulator类层次与Figure类层次是平行(至少部分平行),如下图所示。
Figure类提供了一个CreateManipulator工厂方法,它使得客户可以创建一个与Figure相对应的Manipulator。Figure子类重定义该方法以返回一个合适的Manipulator子类实例。作为一种选择,Figure类可以实现CreateManipulator以返回一个默认的Manipulator实例,而Figure子类可以继承这个缺省的实现。这样的Figure类不需要相应的Manipulator子类----因此该层次只是部分平行的。
9、代码示例
A maze game may be played in two modes, one with regular rooms that are only connected with adjacent rooms, and one with magic rooms that allow players to be transported at random,The regular game mode could use this template method:
In the above snippet, the MazeGame constructor is a template method that makes some common logic. It refers to the makeRoom factory method that encapsulates the creation of rooms such that other rooms can be used in a subclass. To implement the other game mode that has magic rooms, it suffices to override the makeRoom method:
10、相关模式
Abstract Factory经常用工厂方法来实现。
工厂方法通常在Template Method中被调用。在上面代买示例中MazeGame就是一个模板方法,在文档例子中,NewDocument也是一个模板方法。
Prototype不需要创建Creator的子类。但是,它们通常要求一个针对Product类的Initialize操作。Creator使用Initialize来初始化对象。而Factory Method不需要这样的操作。
定义一个用于创建对象的接口,让子类决定实例化哪一个类。Factory Method使一个类的实例化延迟到子类。
2、别名
虚拟构造(Virtual Constructor)
3、动机
框架使用抽象类定义和维护对象之间的关系。这些对象的创建通常也由框架负责。
考虑这样一个框架,它可以向用户展示多个文档。在这个框架中,两个主要的抽象是类Application和Document。这两个类都是抽象的,客户必须通过它们的子类来做与具体应用相关的实现。例如,为创建一个绘图应用,我们定义DrawingApplication和DrawingDocument。Application类负责管理Document并根据需要创建它们----例如,当用户从菜单中选择Open或New的时候。
因为被实例化的特定Document子类是与特定应用相关的,所以Application类不可能预测到哪个Document子类将被实例化----Application类仅知道一个新的文档何时被创建,而不知道哪一个Document将被创建。这就产生了一个尴尬的局面:框架必须实例化类,但是它只知道不能被实例化的抽象类。
Factory Method模式提供了一个解决方案。它封装了哪一个Document子类将被创建的信息并将这些信息从该框架中分离出来。如下图所示
Application的子类重定义Application的抽象操作CreateDocument以返回适当的Document子类对象。一旦一个Application子类实例化以后,它就可以实例化与应用相关的文档,而无需知道这些文档的类。我们称CreateDocument是一个工厂方法(factory method),因为它负责“生产”一个对象。
4、适用性
在下列情况下可以使用Factory Method模式:
当一个类不知道它所创建的对象的类的时候。
当一个类希望由它的子类来指定它所创建的对象的时候。
当类将创建对象的职责委托给多个帮助子类中的某一个,并且你希望将哪一个帮助子类是代理者这一信息局部化的时候。
5、结构
6.参与者
Product(Document)
----定义工厂方法所创建的对象的接口
ConcreteProduct
----实现Product接口
Creator(Application)
----声明工厂方法,该方法返回一个Product类型的对象。Creator也可以定义一个工厂方法的缺省实现,它返回一个缺省的ConcreteProduct。
----可以调用工厂方法创建一个Product对象
ConcreteProduct(MyApplication)
----重定义工厂方法以返回一个ConcreteProduct实例。
7、协作
Creator依赖于它的子类来定义工厂方法,所以它返回一个适当的ConcreteProduct实例。
8、效果
工厂方法不再将与特定应用有关的类绑定到你的代码中。代码仅处理Product接口;因此它可以与用户定义的任何ConcreteProduct类一起使用。
工厂方法的一个潜在缺点在于客户可能仅仅为了创建一个特定的ConcreteProduct对象,就不得不创建Creator的子类。当Creator子类不必需时,客户现在必然要处理类演化的其他方面;但是当客户无论如何必须创建Creator的子类时,创建子类也是可行的。
下面是Factory Method模式的另外两种效果:
1)为子类提供挂钩(hook) 用工厂方法在一个类的内部创建对象通常比直接创建对象更灵活。Factory Method给子类一个挂钩以提供对象的扩展版本。
在Document的例子中,Document类可以定义一个称为CreateFileDialog的工厂方法,该方法为打开一个已有的文档创建默认的文档对话框对象。Document的子类可以重新定义这个工厂方法以定义一个与特定应用相关的文件对话框。在这种情况下,工厂方法就不再抽象了而是提供了一个合理的缺省实现。
2)连接平行的类层次 迄今为止,我们所考虑的例子中,工厂方法并不往往只是被Creator调用,客户可以找到一些有用的工厂方法,尤其在平行类层次的情况下。
当一个类将它的一部分职责委托给一个独立类的时候,就产生了平行类层次。考虑可以被交互操纵的图形;也就是说,它们可以用鼠标进行伸展、移动,或者旋转。实现这样一些交互并不总是那么容易,它通常需要存储和更新在给定时刻记录操纵状态的信息,这个状态仅仅在操纵时需要。因此它不需要被保存在图形对象中。此外,当用户操纵图形时,不同的图形有不同的行为。例如,将直线图形拉长可能会产生一个端点被移动的效果,而伸展正文图形则有可能改变行距。
有了这些限制,最好使用一个独立的Manipulator对象实现交互并保存所需要的任何与特定操纵相关的状态。不同的图形将使用不同的Manipulator子类来处理特定的交互。得到的Manipulator类层次与Figure类层次是平行(至少部分平行),如下图所示。
Figure类提供了一个CreateManipulator工厂方法,它使得客户可以创建一个与Figure相对应的Manipulator。Figure子类重定义该方法以返回一个合适的Manipulator子类实例。作为一种选择,Figure类可以实现CreateManipulator以返回一个默认的Manipulator实例,而Figure子类可以继承这个缺省的实现。这样的Figure类不需要相应的Manipulator子类----因此该层次只是部分平行的。
9、代码示例
A maze game may be played in two modes, one with regular rooms that are only connected with adjacent rooms, and one with magic rooms that allow players to be transported at random,The regular game mode could use this template method:
public class MazeGame { public MazeGame() { Room room1 = makeRoom(); Room room2 = makeRoom(); room1.connect(room2); this.addRoom(room1); this.addRoom(room2); } protected Room makeRoom() { return new OrdinaryRoom(); } }
In the above snippet, the MazeGame constructor is a template method that makes some common logic. It refers to the makeRoom factory method that encapsulates the creation of rooms such that other rooms can be used in a subclass. To implement the other game mode that has magic rooms, it suffices to override the makeRoom method:
public class MagicMazeGame extends MazeGame { @Override protected Room makeRoom() { return new MagicRoom(); } }
10、相关模式
Abstract Factory经常用工厂方法来实现。
工厂方法通常在Template Method中被调用。在上面代买示例中MazeGame就是一个模板方法,在文档例子中,NewDocument也是一个模板方法。
Prototype不需要创建Creator的子类。但是,它们通常要求一个针对Product类的Initialize操作。Creator使用Initialize来初始化对象。而Factory Method不需要这样的操作。
发表评论
-
STRATEGY(策略)——对象行为型模式
2013-06-17 16:19 6841、意图 定义一系列的算法,把它们一个个封装起来,并且 ... -
STATE(状态)—— 对象行为型模式
2013-06-14 16:49 7831、意图 允许一个 ... -
OBSERVER(观察者)——对象行为型模式
2013-06-13 15:36 7041、意图 定义对象 ... -
MEDIATOR(中介者)——对象行为型模式
2013-06-09 16:17 6821、意图 用一个中 ... -
CHAIN OF RESPONSIBILITY(职责链) —— 对象行为型模式
2013-06-06 16:32 6481、意图 使多个对象都有机会处理请求,从而避免请求的发 ... -
PROXY(代理) —— 对象结构型模式
2013-06-05 11:24 7541、意图 为其他对 ... -
DECORATOR(装饰) -—— 对象机构型模式
2013-06-03 11:43 6981、意图 动态地给一个对象添加一些额外的职责。就增加功 ... -
COMPOSITE(组合) ---- 对象结构型模式
2013-05-31 15:12 7721、意图 将对象组 ... -
设计模式的三大分类解析
2013-05-24 14:48 848设计模式在功能上 ... -
TEMPLATE METHOD(模板方法)----- 类行为型模式
2013-04-07 11:27 7011、意图 定义一个 ... -
ADAPTER(适配器) --- 类对象结构型模式
2013-03-28 11:33 5951、意图 将一个类的接口转化成客户希望的另外一个接口。 ... -
BRIGE(桥接) ------ 对象结构型模式
2013-03-27 11:20 7401、意图 将抽象部 ... -
COMMAND(命令) ---- 对象行为型模式
2013-03-06 11:20 7251、意图 将一个请求封装为一个对象,从而使你可用不同的 ... -
VISITOR(访问者) ---- 对象行为型模式
2013-02-26 17:03 9131、意图 表示 ... -
Builder(生成器)---- 对象创建型模式
2013-02-25 15:54 6331、意图 将一个复杂对象的创建和它的表示分离,使得同样的 ... -
ABSTRACT FACTORY(抽象工厂)------ 对象创建型模式
2013-02-22 11:21 6831、意图 提供一个创建一系列相关或相互依赖对象的接口,而 ... -
Flyweight pattern(享元模式)
2013-02-20 14:45 7701. 概述 面向对象技术可以很好地解决系统一些灵活性或可扩展 ... -
Facade模式 --- 对象结构型模式
2013-02-19 17:03 7021、意图 为子系统中 ... -
23个设计模式的名字和意图
2013-02-19 15:41 7221、Abstract Factory:提供 ... -
从MVC理解设计模式
2013-02-19 14:40 776本文将透过MVC来帮助我们理解“模式”这一术语的含义。 ...
相关推荐
### Factory Method 工厂方法模式(创建型模式) #### 概述 在软件工程领域,设计模式是一种在特定上下文中解决常见问题的通用方案。Factory Method(工厂方法)模式是GoF(Gang of Four)设计模式之一,属于创建型...
C#面向对象设计模式纵横谈(5):Factory Method 工厂方法模式(创建型模式) (Level 300)
工厂方法是面向对象设计模式的一种,属于创建型模式。这个模式定义了一个创建对象的接口,但让子类决定实例化哪一个类。工厂方法让类的实例化推迟到子类中进行,从而增加了系统的灵活性。 一、工厂方法模式的基本...
C#面向对象设计模式纵横谈(5):Factory Method 工厂方法模式(创建型模式) 视频教程,主讲人李建忠
工厂方法模式是面向对象设计模式中的一个核心模式,属于创建型模式。它的主要目的是通过引入一个工厂接口,将具体的对象创建过程封装起来,使得客户端在使用时无须关心产品类的确切实现,只需要通过工厂来获取所需的...
工厂方法模式是面向对象设计模式中的行为型模式之一,它提供了一种创建对象的最佳方式。在工厂方法模式中,一个工厂类负责创建对象,而具体的创建过程被延迟到了子类中,使得子类可以在不修改原有代码的基础上决定...
工厂方法(Factory Method)设计模式是面向对象设计中的一种经典模式,它属于创建型设计模式,主要用于解决对象创建的问题。在这个名为“Factory-Method-for-Salary.rar_factory”的项目中,我们将深入探讨如何利用...
工厂方法模式是创建型设计模式的一种,它提供了一种创建对象的最佳方式。 ### 一、什么是工厂方法模式? 工厂方法模式定义了一个创建对象的接口,但让子类决定实例化哪一个类。工厂方法使一个类的实例化延迟到其...
在软件设计模式中,工厂方法(Factory Method)和抽象工厂(Abstract Factory)是两种非常重要的创建型模式。它们主要用于解决对象实例化的问题,提供了一种封装对象创建过程的方法,使得代码更加灵活,易于扩展和...
抽象工厂模式是设计模式中的一种,它属于对象创建型模式,主要解决的是当系统需要创建一组相关或相互依赖的对象时,而这些对象的类在运行时可能未知的问题。这种模式提供了一个接口,用于创建相关或依赖对象的家族,...
工厂方法模式(Factory Method Pattern)是一种创建型设计模式,它定义了一个用于创建对象的接口,但由子类决定实例化哪一个具体类。这样,客户端代码就不需要知道具体的类是什么,只需通过工厂接口获取对象。 工厂...
工厂方法(Factory Method)是面向对象设计模式中的一个基础且广泛应用的模式,它属于创建型模式,主要目的是为了解耦对象的创建过程。本文将深入探讨工厂方法的设计理念、实现方式及其在实际开发中的应用。 ### ...
在软件设计领域,工厂模式是一种常用的创建型设计模式,它提供了一种创建对象的最佳方式。在工厂模式中,我们创建一个工厂类,该类负责创建特定类型的对象,而无需暴露具体的创建逻辑。这样,客户端代码就可以使用...
工厂方法模式是设计模式中的创建型模式之一,它在软件工程中扮演着非常重要的角色。这个模式的主要目的是将对象的创建过程抽象出来,使得创建过程独立于使用对象的客户端,从而提高了系统的可扩展性和可维护性。在这...
工厂方法模式是一种创建型设计模式,它提供了一个创建对象的接口,但允许子类决定实例化哪一个类。这样,工厂方法将类的实例化推迟到子类。在Java中,我们可以定义一个工厂接口,然后由具体的子类实现这个接口,创建...
描述中的“创建型模式-工厂方法模式-最简单的源码-qt工程”表明,这个压缩包可能包含了一个基于Qt框架的C++项目,该项目展示了工厂方法模式的简单应用。Qt是一个跨平台的应用程序开发框架,广泛用于GUI编程,但也...
抽象工厂模式(Abstract Factory)是一种创建型设计模式,用于提供一个创建一系列相关或相互依赖对象的接口,而无需指定它们的具体类。这种模式的关键在于,它允许客户端代码与具体的实现细节解耦,使得添加新的产品...