我相信工厂方法设计模式适合我正在尝试做的事情,但我不确定赋予它多少责任(它创建的子类的知识)。使用 factory method pattern 的示例在 Wikipedia 上几乎完全准确地描述了我所处的情况:
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
功能并跳过开关盒?我以前没有任何使用工厂的经验,我希望从一些过去使用过工厂的人那里得到一些关于处理这个问题的最佳方法的见解。让工厂知道其子类的内部工作是否可以,或者他们是否应该负责让工厂知道要创建哪个,以及如何组织它们?
谢谢!
最佳答案
工厂应该对选择要创建的实际对象有一些想法。例如,WebRequest.Create
.NET 中的方法,应该能够通过检查 Uri
的协议(protocol)部分来在不同的协议(protocol)客户端之间进行选择。 .它不需要解析整个事情。只是区分哪个类将负责它所需的部分(在您的示例中,它可能只是文件头)。
关于你关于打破封装的问题,不是真的......大多数时候,工厂是硬编码的,并且已经知道不同类型的类及其特性。它已经依赖于一组已知类所提供的功能,因此您不会对其添加太多内容。您还可以将工厂的检测部分封装在另一个可以由工厂和子类使用的辅助类中(本着 DRY 原则的精神)。
关于design-patterns - 工厂如何知道要创建哪种类型的对象?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/703467/