我相信工厂方法设计模式适合我正在尝试做的事情,但我不确定给它有多少责任(它创建的子类的知识).在维基百科上使用工厂方法模式的例子描述了我几乎完全正确的情况:
public class ImageReaderFactory { public static ImageReader getImageReader( InputStream is ) { int imageType = figureOutImageType( is ); switch( imageType ) { case ImageReaderFactory.GIF: return new GifReader( is ); case ImageReaderFactory.JPEG: return new JpegReader( is ); // etc. } } }
我的问题是,该figureOutImageType
功能是什么样的?在这个具体的例子中,我假设它检查一个文件头InputStream
以确定数据所在的图像格式.我想知道ImageReaderFactory
它自己是否知道如何解析文件头并确定文件类型是否为GIF,JPEG等等,或者如果它调用每个Reader
类中的一个函数,让它知道它是什么类型的图像.这样的事情,也许:
int figureOutImageType(InputStream is) { if(GifReader.isGIF(is)) return ImageReaderFactory.GIF; else if(JpegReader.isJPEG(is)) return ImageReaderFactory.JPEG; // etc. }
似乎让工厂知道如何解析图像破解封装,并让子类决定应该创建哪一个是工厂方法设计模式的一部分.然而,似乎figureOutImageType
函数只是添加了一些冗余代码,因为为什么不让每个子类InputStream
对getImageReader
函数中的函数执行检查并跳过switch case?
我以前没有任何使用过工厂的经验,我希望从过去使用它们的一些人那里得到一些见解,以解决这个问题的最佳方法.是否可以让工厂了解其子类的内部工作原理,或者他们是否应该负责让工厂知道要创建哪个,以及如何组织它?
谢谢!
工厂应该对选择要创建的实际对象有所了解.例如,WebRequest.Create
.NET中的方法应该能够通过检查协议部分来选择不同的协议客户端Uri
.它不需要解析整个事情.只需要区分哪个类将负责它(在您的示例中,它可能只是文件头).
关于打破封装的问题,不是真的...大多数时候,工厂都是硬编码的,并且已经知道不同类型的类及其功能.它已经取决于已知类集提供的功能,因此您不会添加太多内容.您还可以将工厂的检测部分封装在另一个辅助类中,该辅助类可以由工厂和子类使用(在DRY原则的精神中).