设计模式可复用面向对象软件的基础 第3章 创建型模式(3)

2021-09-24 20:27

AbstractFactory将产品对象的创建延迟到它的 C o n c r e t e F a c t o r y子类。

8. 效果 A b s t r a c t F a c t o r y模式有下面的一些优点和缺点:

1) 它分离了具体的类 Abstract Factory模式帮助你控制一个应用创建的对象的类。因为一个工厂封装创建产品对象的责任和过程,它将客户与类的实现分离。客户通过它们的抽象接口操纵实例。产品的类名也在具体工厂的实现中被分离;它们不出现在客户代码中。

2) 它使得易于交换产品系列一个具体工厂类在一个应用中仅出现一次—即在它初始化的时候。这使得改变一个应用的具体工厂变得很容易。它只需改变具体的工厂即可使用不同的产品配置,这是因为一个抽象工厂创建了一个完整的产品系列,所以整个产品系列会立刻改变。在我们的用户界面的例子中,我们仅需转换到相应的工厂对象并重新创建接口,就可实现从M o t i f窗口组件转换为Presentation Manager窗口组件。

3) 它有利于产品的一致性当一个系列中的产品对象被设计成一起工作时,一个应用一次只能使用同一个系列中的对象,这一点很重要。而 A b s t r a c t F a c t o r y很容易实现这一点。

4) 难以支持新种类的产品难以扩展抽象工厂以生产新种类的产品。这是因为 A b s t r a c t F a c t o r y接口确定了可以被创建的产品集合。支持新种类的产品就需要扩展该工厂接口,这将涉及A b s t r a c t F a c t o r y类及其所有子类的改变。我们会在实现一节讨论这个问题的一个解决办法。

9. 实现下面是实现Abstract Factor模式的一些有用技术:

1) 将工厂作为单件一个应用中一般每个产品系列只需一个 C o n c r e t e F a c t o r y的实例。因此工厂通常最好实现为一个 S i n g l e t o n(3 . 5)。

2) 创建产品 A b s t r a c t F a c t o r y仅声明一个创建产品的接口,真正创建产品是由 C o n c r e t e P r o d u c t子类实现的。最通常的一个办法是为每一个产品定义一个工厂方法(参见 Factory Method(3 . 3))。一个具体的工厂将为每个产品重定义该工厂方法以指定产品。虽然这样的实现很简单,但它却要求每个产品系列都要有一个新的具体工厂子类,即使这些产品系列的差别很小。

C l i e n t—仅使用由 A b s t r a c t F a c t o r y和A b s t r a c t P r o d u c t类声明的接口。

本书设计实例从面向对象的设计中精选出23个设计模式,总结了面向对象设计中最有价值的经验,并且用简洁可复用的形式表达出来。本书分类描述了一组设计良好,表达清楚的软件设计模式,这些模式在实用环境下有特别有用

如果有多个可能的产品系列,具体工厂也可以使用 P r o t o t y p e(3 . 4)模式来实现。具体工厂使用产品系列中每一个产品的原型实例来初始化,且它通过复制它的原型来创建新的产品。在基于原型的方法中,使得不是每个新的产品系列都需要一个新的具体工厂类。

此处是S m a l l t a l k中实现一个基于原型的工厂的方法。具体工厂在一个被称为 p a r t C a t a l o g的字典中存储将被复制的原型。方法 m a k e:检索该原型并复制它:

make : partName ^ (partCatalog at : partName) copy

具体工厂有一个方法用来向该目录中增加部件。

addPart : partTemplate named : partName partCatalog at : partName put : partTemplate

原型通过用一个符号标识它们,从而被增加到工厂中:

aFactory addPart : aPrototype named : #ACMEWidget

在将类作为第一类对象的语言中(例如 S m a l l t a l k和O b j e c t i v e C),这个基于原型的方法可能有所变化。你可以将这些语言中的一个类看成是一个退化的工厂,它仅创建一种产品。你可以将类存储在一个具体工厂中,这个具体工厂在变量中创建多个具体的产品,这很像原型。这些类代替具体工厂创建了新的实例。你可以通过使用产品的类而不是子类初始化一个具体工厂的实例,来定义一个新的工厂。这一方法利用了语言的特点,而纯基于原型的方法是与语言无关的。

像刚讨论过的 S m a l l t a l k中的基于原型的工厂一样,基于类的版本将有一个唯一的实例变量p a r t C a t a l o g,它是一个字典,它的主键是各部分的名字。 p a r t C a t a l o g存储产品的类而不是存储被复制的原型。方法m a k e:现在是这样:

make : partName ^ (partCatalog at : partName) new

3) 定义可扩展的工厂 A b s t r a c t F a c t o r y通常为每一种它可以生产的产品定义一个操作。产品的种类被编码在操作型构中。增加一种新的产品要求改变 A b s t r a c t F a c t o r y的接口以及所有与它相关的类。一个更灵活但不太安全的设计是给创建对象的操作增加一个参数。该参数指定了将被创建的对象的种类。它可以是一个类标识符、一个整数、一个字符串,或其他任何可以标识这种产品的东西。实际上使用这种方法, A b s t r a c t F a c t o r y只需要一个“ M a k e”操作和一个指示要创建对象的种类的参数。这是前面已经讨论过的基于原型的和基于类的抽象工厂的技术。

C + +这样的静态类型语言与相比,这一变化更容易用在类似于 S m a l l t a l k这样的动态类型语言中。仅当所有对象都有相同的抽象基类,或者当产品对象可以被请求它们的客户安全的强制转换成正确类型时,你才能够在 C + +中使用它。Factory Method(3.3)的实现部分说明了怎样在C + +中实现这样的参数化操作。

该方法即使不需要类型强制转换,但仍有一个本质的问题:所有的产品将返回类型所给定的相同的抽象接口返回给客户。客户将不能区分或对一个产品的类别进行安全的假定。如果一个客户需要进行与特定子类相关的操作,而这些操作却不能通过抽象接口得到。虽然客户可以实施一个向下类型转换( d o w n c a s t)(例如在C + +中用d y n a m i c _ c a s t),但这并不总是可行或安全的,因为向下类型转换可能会失败。这是一个典型的高度灵活和可扩展接口的权衡 折衷。

本书设计实例从面向对象的设计中精选出23个设计模式,总结了面向对象设计中最有价值的经验,并且用简洁可复用的形式表达出来。本书分类描述了一组设计良好,表达清楚的软件设计模式,这些模式在实用环境下有特别有用

10. 代码示例我们将使用Abstract Factory模式创建我们在这章开始所讨论的迷宫。类M a z e F a c t o r y可以创建迷宫的组件。它建造房间、墙壁和房间之间的门。它可以用于一

设计模式可复用面向对象软件的基础 第3章 创建型模式(3).doc 将本文的Word文档下载到电脑 下载失败或者文档不完整,请联系客服人员解决!

下一篇:教育法、教师法、义务教育法、未成年人保护法法律填空

相关阅读
本类排行
× 注册会员免费下载(下载后可以自由复制和排版)

马上注册会员

注:下载文档有可能“只有目录或者内容不全”等情况,请下载之前注意辨别,如果您已付费且无法下载或内容有问题,请联系我们协助你处理。
微信: QQ: