Design patterns 工厂方法哪种方法

Design patterns 工厂方法哪种方法,design-patterns,factory-pattern,Design Patterns,Factory Pattern,我很难理解工厂方法模式。从这里的例子:和这里:: 哪一个是事实上的“工厂方法”:getImageReader()或“简而言之,工厂方法封装了对象的创建。它们为您创建复杂的对象,因此您不必费心 在您的示例中: public class ImageReaderFactory { public static ImageReader getImageReader(InputStream is) { int imageType = figureOutImageType( is );

我很难理解工厂方法模式。从这里的例子:和这里::


哪一个是事实上的“工厂方法”:getImageReader()或“简而言之,工厂方法封装了对象的创建。它们为您创建复杂的对象,因此您不必费心

在您的示例中:

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.
        }
    }
}
谁在创建
ImageReader
对象(调用它们的构造函数)并返回它们?既不是
figureOutImageType()
,也不是
GifReader
类的方法(或其他
JpegReader
或可能是
PngReader
TiffReader
etcReader

最终,
getImageReader()
正在为您创建它们。这是您调用的方法,询问“嘿,给我创建一个
ImageReader
,请”
,它会完成剩下的工作

因此,
publicstaticimagereader getImageReader(InputStream是){}
是最接近工厂方法的(见下面的更新)



更新: 请记住,这种设计并不是严格意义上的“工厂方法模式”。这一点很重要

原因已在中讨论过,请允许我(稍作修改):

(…)这段代码不是“工厂方法OO设计模式”的正确实现,因为它不满足“类延迟实例化到子类”。不过,就我个人而言,我可以自由地将此解决方案称为“工厂方法”。
要使其成为真正的工厂方法模式,您需要允许该方法被子类覆盖。例如,工厂类(
ImageReaderFactory
)需要是可扩展的(即非
),并且
getImageReader
需要是
抽象的


我不同意acdcjunior的回答。他描述的是简单的工厂模式。 工厂方法模式涉及定义接口,以便:

  • 具体的实现者可以实现
  • 客户机可以用来创建产品(可能实现一些接口)和抽象产品创建的细节
  • 更新:来自维基百科:

    该模式的本质是“定义一个接口来创建 对象,但由实现接口的类决定 类来实例化。工厂方法允许类延迟 实例化到子类。”

    (另请参见此处的代码示例)

    更新2:

    回答你的问题:


    哪一个是事实上的“工厂方法”:getImageReader()或“看一看,我的意思是”getImageReader()或“你所说的是什么”
    返回的类GifReader/JpegReader将有一个方法,称为read(),或c++-ish“否,
    GifReader.read()
    JpegReader.read()
    仅为您提供读取图像的功能。请注意,该代码段需要的是一个
    ImageReader
    ,而不是
    Image
    ,因此工厂是构建
    ImageReader
    的人。
    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.
            }
        }
    }