一个类看成是一个退化的工厂,它仅创建一种产品。你可以将类存储在一个具体工厂中,这个具体工厂在变量中创建多个具体的产品,这很像原型。这些类代替具体工厂创建了新的实例。你可以通过使用产品的类而不是子类初始化一个具体工厂的实例,来定义一个新的工厂。这一方法利用了语言的特点,而纯基于原型的方法是与语言无关的。像刚讨论过的Smalltalk中的基于原型的工厂一样,基于类的版本将有一个唯一的实例变量partCatalog,它是一个字典,它的主键是各部分的名字。partCatalog存储产品的类而不是存储被复制的原型。方法make:现在是这样:
makepartNamepartCatalogatpartName
ew
3定义可扩展的工厂AbstractFactory通常为每一种它可以生产的产品定义一个操作。产品的种类被编码在操作型构中。增加一种新的产品要求改变AbstractFactory的接口以及所有与它相关的类。一个更灵活但不太安全的设计是给创建对象的操作增加一个参数。该参数指定了将被创建的对象的种类。它可以是一个类标识符、一个整数、一个字符串,或其他任何可以标识这种产品的东西。实际上使用这种方法,AbstractFactory只需要一个“Make”操作和一个指示要创建对象的种类的参数。这是前面已经讨论过的基于原型的和基于类的抽象工厂的技术。C这样的静态类型语言与相比,这一变化更容易用在类似于Smalltalk这样的动态类型语言中。仅当所有对象都有相同的抽象基类,或者当产品对象可以被请求它们的客户安全的强制转换成正确类型时,你才能够在C中使用它。FactoryMethod33的实现部分说明了怎样在C中实现这样的参数化操作。该方法即使不需要类型强制转换,但仍有一个本质的问题:所有的产品将返回类型所给定的相同的抽象接口返回给客户。客户将不能区分或对一个产品的类别进行安全的假定。如果一个客户需要进行与特定子类相关的操作,而这些操作却不能通过抽象接口得到。虽然客户可以实施一个向下类型转换(dow
cast)(例如在C中用dy
amic_cast),但这并不总是可行或安全的,因为向下类型转换可能会失败。这是一个典型的高度灵活和可扩展接口的权衡折衷。
f10代码示例我们将使用AbstractFactory模式创建我们在这章开始所讨论的迷宫。类MazeFactory可以创建迷宫的组件。它建造房间、墙壁和房间之间的门。它可以用于一个从文件中读取迷宫说明图并建造相应迷宫的程序。或者它可以被用于一个随机建造迷宫的程序。建造迷宫的程序将r