工厂模式辨析与应用研究

2011-10-16 08:13吴清寿
长春师范大学学报 2011年2期
关键词:设计模式实例代码

吴清寿

(武夷学院数学与计算机系,福建武夷山 354300)

工厂模式辨析与应用研究

吴清寿

(武夷学院数学与计算机系,福建武夷山 354300)

通过使用工厂模式封装了易变对象,屏蔽了客户需求变化的负面影响,解决了客户和具体对象的紧耦合。本文讨论工厂模式中简单工厂模式、工厂方法模式和抽象工厂模式的基本结构,并对其适用场景和优缺点进行深入剖析。为进一步降低客户对工厂对象的依赖,用1NET中的反射机制和配置文件动态地创建工厂对象。

设计模式;工厂模式;设计原则;反射;配置文件

用面向对象技术开发应用系统,实例化对象是不可避免的而且是很频繁的。当所实例化的对象是稳定的,也就是不会经常变化,这时并没有问题。当所实例化的对象因需求变化而经常发生变化,这将造成客户代码的不稳定,因为每一次对象的变更都需要修改客户代码。需求变化可能不仅仅是变更对象,还可能需要增删对象,此时原来的系统将发生剧烈变化,需要修改的部分不止是一行或几行代码,而可能是结构上的变化,这种修改有时是灾难性的,因为可能引起系统中多个子系统的变化。

面向对象的一个重要设计原则就是封装变化点,封装指的是任何形式的隐藏,包括数据隐藏、实现隐藏、类隐藏、设计隐藏和实例化隐藏,本文特指实例化隐藏。如果有一个组件能够用于封装对象的创建和管理,而客户只和该组件交互,这样将大幅度减少客户对具体对象的依赖,从而达到客户代码的相对稳定。设计模式中的工厂模式为解决该问题提供了一种可能,它通过专门的类用于实例化并获得对象,这个类称为工厂。根据实例化的时机、所创建对象的层次结构和关联度,这里把工厂模式划分为简单工厂模式、工厂方法模式和抽象工厂模式。

1 工厂模式概述

1.1 简单工厂模式

简单工厂模式的意图:实例化对象,而不需要客户了解这个对象属于哪个具体的子类[1-2]。通常由一个工厂对象决定创建出哪一种产品类的实例,简单工厂模式并不属于G OF23种模式,通常作为工厂方法模式的一个特例加以讨论,这里将其单独作为一种模式讨论有助于更全面把握工厂模式的本质。

从图1中可以看到,客户 (Client)扮演着产品消费者的角色,它只依赖于工厂 (Factory)和抽象产品(Product),但它不知道也不需要知道到底有哪些具体产品,其所需的一切产品由工厂提供,这种结构解耦了客户和具体产品类。当具体产品类发生变化时,客户中的代码无需修改,这符合开闭原则。

对工厂而言,它必须知道所有的产品,它还负责创建产品并将产品提供给客户,如果产品类型发生变更,则需要修改工厂。

1.2 工厂方法模式

工厂方法模式的意图:定义一个用于创建对象的接口,让子类决定实例化哪一个类。工厂方法使一个类的实例化延迟到其子类[1,4]。

图1 简单工厂模式结构

在图2中,Creator声明工厂方法FactoryMethod()返回一个Product类型的对象,ConcreteCreator重定义工厂方法以返回一个ConcreteProduct实例。这里的核心是工厂方法FactoryMethod(),在Creator类中它是抽象的,而在ConcreteCreator类中它将根据需要实例化具体产品类并将其返回给客户。这样的好处是当增加一个新产品,原来的ConcreteCreator类不需要修改,所要做的工作就是再增加一个ConcreteCreator类并实现Facto2 ryMethod()方法,用以创建和返回新产品。

图2 工厂方法模式结构

1.3 抽象工厂模式

抽象工厂模式的意图:提供一个创建一系列相关或相互依赖对象的接口,而无需指定它们具体的类[1,4]。在图3中,AbstractProductA和AbstractProductB代表多个产品系列的抽象,具体产品则由具体工厂创建,Client只使用AbstractProduct和AbstractFactory类声明的接口,无需了解具体产品细节。所以,抽象工厂的主要作用就是提供一种封装机制来解决客户和多系列具体对象创建工作的紧耦合。

2 工厂模式辨析

通过对三个模式的共性和差异进行探讨,了解其主要应用场景及优缺点,将有助于在具体的系统设计中选择合适的设计模式。

2.1 共性

工厂模式属于创建型模式,其最核心的功能就是封装具体类的信息并隐藏这些类实例的创建过程,减少系统中对象之间的紧耦合关系,降低因需求频繁变化引起的系统框架变动和代码修改,为系统扩展留下空间,从而使得系统更有弹性。工厂模式遵循针对接口编程的原则,用接口代替将来可能变化的对象,依靠工厂类或工厂方法负责具体对象创建工作,降低客户对具体对象的依赖性,满足系统变化的需求。

2.2 优缺点

图3 抽象工厂模式结构

简单工厂模式中工厂类负责具体产品的实例化工作,其优点是隔离了客户端和具体产品,使得客户端相对独立于具体产品的创建过程,在系统引入新产品时无需修改客户端,但需要修改工厂类。

工厂方法模式利用多态性对简单工厂模式进行了抽象和推广,克服了简单工厂模式中需要经常修改工厂类的缺点。原来的工厂类变成了抽象类,并给出具体工厂子类要实现的接口即工厂方法,本身不再决定具体产品的实例化,而是由子类决定创建哪个具体产品。当引入新产品,原来的具体工厂保持不变,只需增加一个新的具体工厂。这种结构符合开闭原则,为具有稳定接口的产品系列频繁变化提供了封装机制。工厂方法模式虽然解耦了客户端和具体产品,但增加了客户端和具体工厂的耦合,我们可以利用1NET中的反射机制来解决这种耦合问题。

抽象工厂模式提供一个抽象接口 (接口或抽象类)用来创建产品家族,其具体子类提供负责在抽象工厂中创建产品的方法,通常以工厂方法来实现。抽象工厂模式使得易于更换产品系列,一个具体工厂对应一个产品系列,在系统中只需改变具体工厂就可以使用不同的产品。抽象工厂模式难以支持新种类的产品,因为抽象工厂接口确定了可以被创建的产品集合,增加新产品就意味着需要扩展工厂接口,这将造成抽象工厂和所有子类都需要改变接口。

另外,工厂方法模式属于类创建型模式,它使用继承改变被实例化的类,而抽象工厂模式属于对象创建型模式,它将实例化委托给另一个对象。

3 基于反射机制的工厂模式

3.1 反射机制概述

反射 (Reflection)是1NET中的重要机制,通过反射,系统具有审查元数据并收集关于它的类型信息的能力,可以在运行时获得1NET中每一个类型的成员,包括方法、属性、事件以及构造函数等。获得了构造函数的信息,即可动态创建对象,该功能为简化工厂模式应用提供了一种解决方案。

3.2 从配置文件中读取类型名称

为了避免将类型名称硬编码在代码中,可以将类型名存储在ASP1NET应用程序的web1config文件中或Windows应用程序的app1config文件中。类型名存储为键/值对的形式,可以在运行时使用key查找存储在AppSettings属性中的值。在应用程序的app1config文件的节点中添加以下代码:

3.3 反射机制在工厂模式中的应用

利用CreateInstance方法可以动态创建工厂对象,其中程序集名称一般比较稳定,因而可以直接在代码中嵌入。而根据不同的需求,客户所使用的工厂经常发生变化,这时,可以通过读取配置文件来获得工厂类型名称,当需要更换工厂时,只需更改配置文件中value即可,或者在代码中更改key所对应的工厂类型名称。

从以上代码可以看出,客户没有与具体产品耦合,也没有与具体工厂耦合,反射机制通过动态创建对象使得程序框架更加具有弹性和灵活性。在对于简单工厂模式、工厂方法模式和抽象工厂模式的应用中,虽然细节上略有不同,但基本原理和操作方式与上述过程类似。

4 结语

实际上所有的创建型模式都是工厂模式,因为它们所解决的主要问题就是对象的创建和管理工作。针对如何创建对象、谁来创建对象、何时创建对象等问题,工厂模式提供了一些颇具弹性的解决办法,从而有助于保持系统中对象内聚、解耦和可测试。

在遵循面向对象设计原则方面,开闭原则 (OCP)、依赖倒置原则 (DIP)和Liskov替换原则 (LSP)为工厂模式实施提供了主要根据[3,5]。开闭原则使得系统更具健壮性、可维护性和可重用性,依赖倒置原则指出了工厂模式实现的主要技术手段之一,即使得高层策略模块在创建类的实例时无需依赖于这些类的具体实现,Liskov替换原则中子类型的可替换性使得使用基类型表示的模块在无需修改的情况下就可以扩展,增加了工厂模式处理多变对象的灵活性。

工厂模式虽然具有很多优点,但会增加设计的复杂性,如为了创建一个新类,就需要该对象的接口类及具体实现类和创建该对象的工厂类。所以,如果要实例化的对象是稳定的或相对稳定的,这时并不需要使用工厂模式。

使用反射机制可以动态地创建实例,在程序中合理地使用反射可以使程序更加灵活。但是使用反射动态绑定时也需要牺牲性能,所以在程序中也要综合考虑这些方面的因素来决定是否要用。

[1]Gamma E,Helm R,Johnson R,et al.设计模式:可复用面向对象软件的基础[M].北京:机械工业出版社,2000.

[2]甑镭..NET与设计模式[M].北京:电子工业出版社,2005.

[3]Martin E,Martin M.敏捷软件开发:原则、模式与实践(C#版)[M].北京:人民邮电出版社,2008.

[4]Gamma E,Helm R,Johnson R,et al.Design patterns:element s of reusable object oriented systems[M].Boston:Addison Wesley,1995.

[5]阎宏.Java与模式[M].北京:电子工业出版社,2002.

[6]郭晓峰,姚世军,尹祖伟.基于.NET的Web应用框架的设计与应用[J].计算机工程与设计,2008,29(2):454-455.

[7]汤国华,叶丹,徐罡.基于设计模式的通用数据库视图生成方法[J].计算机辅助工程,2008,17(1):47.

[8]何泓伟,曲朝阳.设计模式混合的构造方法研究及应用[J].计算机工程与设计,2007,28(5):999-1000.

Analysis and Applied Research on Factory Patterns

WU Qing-shou
(Department of Mathematics and Computer Science of Wuyi University,Wuyishan 354300,China)

By the factory patterns,the volatile objects are sealed,negative impacts of changeable customer needs are shield2 ed,and the problem of tightly coupling between customers and concrete objects is resolved.The basic structures of simple factory pattern,factory method and abstract factory pattern in the factory patterns are discussed.In-depth analysison its ap2 plicability to scenes and advantage and weakness is also conducted.T o further reduce customersπreliance on factoryobjects,factory objects are dynamically created based on the.NET reflection mechanism and the configuration file.

design pattern;factory pattern;design principles;reflection;configuration file

TP31115

A

1008-178X(2011)02-0030-04

2011-01-10

吴清寿 (1977-),男,福建莆田人,武夷学院数学与计算机系讲师,硕士,从事软件工程、1NET技术及分布式系统设计研究。

猜你喜欢
设计模式实例代码
“1+1”作业设计模式的实践探索
三维协同设计模式下的航天项目管理实践与展望
交通机电工程设计模式创新探讨
创世代码
创世代码
创世代码
创世代码
完形填空Ⅱ
完形填空Ⅰ
互动式设计模式研究