3

我无法理解工厂方法模式。从此处的示例:http ://worldwardiary.com/history/Factory_method_pattern#Using_the_factory_pattern和此处:https ://stackoverflow.com/a/806942/2420939 :

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.
        }
    }
}

哪一个是事实上的“工厂方法”:getImageReader() 还是 GifReader 类的“<<”方法?

4

2 回答 2

3

简而言之,工厂方法封装了对象的创建。他们为您创建复杂的对象,因此您不必费心。

在您的示例中:

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请为我创建一个”的方法,然后它会完成其余的工作。

因此,充其量public static ImageReader getImageReader(InputStream is) {}是最接近工厂方法的(参见下面的更新)。



更新:

请记住,这种设计并不是严格意义上的“工厂方法模式”。这它的一个变体

其原因已在其他答案中讨论过,因此请允许我在这里引用一个(稍作改编):

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

于 2013-05-25T20:24:14.447 回答
2

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

  1. 具体实施者可以实施
  2. 客户端可以用来创建产品(可能实现一些接口)和抽象产品创建的细节。

更新: 来自维基百科的工厂方法文章:

这种模式的本质是“定义一个用于创建对象的接口,但让实现该接口的类决定实例化哪个类。工厂方法让一个类将实例化推迟到子类。”

(另见那里的代码示例)。

更新2:

回答你的问题:

哪一个是事实上的“工厂方法”:getImageReader() 还是 GifReader 类的“<<”方法?

它们都没有,因为不涉及抽象。getImageReader只是“工厂方法”,而不是“工厂方法模式”。

于 2013-05-25T20:34:53.917 回答