3

I have trouble understanding factory method pattern. From the example here: http://worldwardiary.com/history/Factory_method_pattern#Using_the_factory_pattern and here: 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.
        }
    }
}

Which one is de-facto "factory method": getImageReader() or the "<<" method of the GifReader class?

Community
  • 1
  • 1
user5185
  • 149
  • 2
  • take a look [here](http://www.oodesign.com/factory-pattern.html) and [here](http://www.dofactory.com/Patterns/PatternFactory.aspx) and – T I May 25 '13 at 20:27

2 Answers2

3

In a nutshell, factory methods encapsulate the creation of objects. They create complex objects for you so you don't have to bother.

In your example:

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

Who's creating the ImageReader objects (calling their constructors) and returning them? Neither figureOutImageType() or the method of the GifReader class (or the others JpegReader or possibly PngReader, TiffReader, etcReader...).

Ultimately, getImageReader() is creating them for you. This is the method you call asking "hey, create me a ImageReader, please" and it does the rest.

So, at best, public static ImageReader getImageReader(InputStream is) {} is the closest (see update below) to a factory method.



Update:

Bear in mind this design is not strictly a "Factory Method Pattern". This is presented as a variant of it.

The reason for this has been discussed in other answers, so allow me to just quote one here (slightly adapted):

(...) this snippet is not a proper implementation of the "Factory Method OO Design Pattern", since it does not satisfy "a class defer instantiation to subclasses." Though, personally I would freely refer to this solution as "factory method".
To make it real factory method pattern, you need to allow the method to be overridden by subclasses. I.e. factory class (ImageReaderFactory) needs to be extensible (i.e. non-static), and getImageReader needs to be abstract.

Community
  • 1
  • 1
acdcjunior
  • 132,397
  • 37
  • 331
  • 304
  • sry, I meant "getImageReader() or the "<<" method of the GifReader class" -- see edit to my question. – user5185 May 25 '13 at 20:32
  • What do you mean by *"`<<` method of the `GifReader` class"*? – acdcjunior May 25 '13 at 20:34
  • the returned class GifReader/JpegReader will have a method, called read() , or c++-ish "<<" operator. – user5185 May 25 '13 at 20:45
  • No, `GifReader.read()` or `JpegReader.read()` would just provide you the functionality of reading the image. Notice that what that snippet wants is a `ImageReader`, not an `Image`, so the factory is the one whos building `ImageReader`s. – acdcjunior May 25 '13 at 20:53
2

I disagree with acdcjunior's answer. What he describes is plain factory pattern. Factory method pattern involves defining interface in order for:

  1. concrete implementer could implement
  2. client could use to both create product (possibly implementing some interface) and abstract over details of product creation.

UPDATE: Factory method article from wikipedia:

The essence of this pattern is to "Define an interface for creating an object, but let the classes that implement the interface decide which class to instantiate. The Factory method lets a class defer instantiation to subclasses."

(see also code example there).

UPDATE2:

Answering your question:

Which one is de-facto "factory method": getImageReader() or the "<<" method of the GifReader class?

None of them, since there is no abstraction involved. getImageReader is just a "method of the factory", but not "factory method pattern".

Eugene Loy
  • 12,224
  • 8
  • 53
  • 79