Understand one Simple Factory Pattern

Keywords: Factory Pattern, Design Pattern


在网上经常会看到有关Factory Pattern的文章, 今天我也在blog上发表一下对一个非常简单Factory pattern的见解.


Factory模式其实就是为了封装系统的变化点, 将变化点集中在一起, 一旦这些变化点真的发生变化时, 只要修改一处代码就可以了.


一图胜万言, figure1是表述这样的一个应用: (1)用户选择一个压缩文件, 然后解压. (2)用户选择一个压缩文件, 然后将它转换成自解压格式. 面对这样的需求, 我们该做什么样的结构设计呢?



figure1


初步设计是: 目前流行的压缩格式有zip和rar等. 我们会抽象一个压缩格式处理器这样的基类(命名为CompressBase), 不同压缩格式的解压和压缩算法不同, 所以我们又会设计出CompressBase的几个派生类, 比如ZipCompress和RarCompress. 用户可能会选择一个zip文件需要我们处理, 也可能选择一个rar文件. 在程序中, 到底要实例化哪个派生类呢? 一个简单的方法是, 通过文件的扩展名, 作为判断的依据. 最开始, 实现Scenario A中的代码为:



public void Decompress(string fileName)

{

CompressBase compressObj=null ;

string fileExtenstion= FileHelper.GetExtension(fileName) ;

switch (fileExtenstion)

{

case "zip":

{

compressObj= new ZipCompress(fileName);

break ;

}

case "rar"


{

compressObj= new ZipCompress(fileName);

break ;

}

default:

{

return ;

}

}



//uncompress the file


compressObj.Decompress() ;

}

同样, 在实现Scenario B的MakeSelfExe()也和上面代码相似. 这样做有什么问题呢? 问题之一, 如果系统要增加对7zip格式的支持, 需要修改所有生成CompressBase对象的地方. 问题之二, 如果我们不采用通过文件扩展名来判断压缩格式的方法, 而是采用更好的算法时, 也需要在程序中到处修改生成CompressBase对象的代码.


较好的设计方案是: 设计一个Factory类, 它具有一个静态的CreateInstance(string fileName), 该方法封装了生成CompressBase类的算法. 刚开始可以继续采用根据扩展名来生成不同的CompressBase子类. 在要生成 即使将来更新算法或增加新的压缩格式, 也只需要更新CreateInstance().


适用性:


(1) 如果可以确定一个系统中, 仅有Scenario A这个场合, 不会有其他类似的功能, 就没有必要使用这种模式.


(2) 对于Scenario A, 这个场景的入口是唯一的. 如果操作的入口和派生类的个数一样的话, 也没有必要使用这种模式, 比如在画图程序中, 虽然Triangle类和Rectangle类都是Shape类的子类, 但画图程序的工具面板上有画三角和矩形两个ToolButton, 也没有必要再创建一个Factory类来负责生成派生类对象.

posted @ 2011-08-28 22:10  harrychinese  阅读(147)  评论(0编辑  收藏  举报