Encyclopedia > Factory method pattern

  Article Content

Factory method pattern

A software design pattern factory pattern is used for computer programming.

See also: Design pattern, Abstract factory pattern, ClassFactory[?]

from mode-x.com (http://www.mode-x.com/index.php?id=24) (contributed by author):

Factory design pattern in Java

The Factory pattern is useful to solve a common problem: Very often you'll have to construct an object, based on some input, and the functions inside the object will depend upon the input. A good example would be a class to read image files and make thumbnails out of them. You could, of course, bung them all into one class and have it decide which bit of code to run on its own:

 public class ImageReader
 {
 	private int FileType;
 	private String FileContents;
 	private byte[] DecodedImage;
 	
 	public ImageReader( InputStream in )
 	{
 		// Figure out what type of file this input stream represents
 		// (eg gif, jpeg, png, tif, etc )
 		
 		FileType = file_type;
 		
 		decodeFile();
 	}
 	
 	private decodeFile()
 	{
 		switch( FileType )
 		{
 			case ImageReader.GIF:
 				// do gif decoding (many lines)
 				break;
 			case ImageReader.JPEG:
 				// do jpeg decoding (many lines)
 				break;
 			case ImageReader.PNG:
 				// do png decoding (many lines)
 				break;
 			// etc...
 		}
 	}
 }
 1 - A bad way to design the ImageReader

This method has the advantage of abstracting the file type from the class that calls this ImageReader, but as the number of file types supported gets larger, the code will quickly become huge, unwieldy and hard to maintain.

Another solution that seems possible is to have a separate object for each of these file types:

 public Interface ImageReader
 {
 	public ImageReader( InputStream in );
 	public getDecodedImage();
 }
 
 public class GifReader implements ImageReader
 {
 	public GifReader( InputStream in )
 	{
 		// check that it's a gif, throw exception if it's not, then if it is
 		// decode it.
 	}
 	public getDecodedImage()
 	{
 		return DecodedImage;
 	}
 }
 public class JpegReader implements ImageReader
 {
 	/....
 }
 
 // Then you would use them as:
 public class MyProg
 {
 	public static void main( String[] args )
 	{
 		String filename = args[0];
 		ImageReader out;
 		
 		if( endsIndotgif( filename ) )
 		{
 			out = (ImageReader)new GifReader( file_input_stream );
 		}
 		if( endsIndotjpeg( filename ) )
 		{
 			out = (ImageReader)new JpegReader( file_input_stream );
 		}
 		
 		printOut( out.getDecodedImage );
 	}
 }
 2 - Another better, but still not so good way to read images

Again, there are advantages to this method (clean organisation of the ImageReader classes, split up in several classes), but this is at the cost of the abstraction of the image type. Again, when you get to have dozens of file types, this will be unsatisfactory and produce code that is hard to maintain.

So what's the solution? Simply to take the best of both worlds, by using the Factory pattern (which you should already have an idea of by now). The Factory is a class that returns another class depending on the context. So in this situation, keeping the separate class design as in the last example:

 public class ImageReaderFactory
 {
 	public static getImageReader( InputStream is )
 	{
 		int ImageType = figureOutImageType( is );
 		
 		switch( ImageType )
 		{
 			case ImageReaderFactory.GIF:
 				GifReader r = new GifReader( is );
 				return( (ImageReader)r );
 				break;
 			case ImageReaderFactory.JPEG:
 				JpegReader r = new JpegReader( is );
 				return( (ImageReader)r );
 				break;
 			// etc.
 		}
 	}
 }
 3 - A good design for the ImageReader: The Factory design pattern

Et voilą! That's all there is to it. The Factory pattern, while not so complex as to be awe-inspiring, is a neat solution to a problem that occurs fairly often. Next time you see a situation where you need a different object depending on the context, you'll think of the Factory pattern.



All Wikipedia text is available under the terms of the GNU Free Documentation License

 
  Search Encyclopedia

Search over one million articles, find something about almost anything!
 
 
  
  Featured Article
242

... 200s 210s 220s 230s - 240s - 250s 260s 270s 280s 290s Years: 237 238 239 240 241 - 242 - 243 244 245 246 247 Events Patriarch Titus[?] succeeds Patriarch Eugenius ...

 
 
 
This page was created in 39.6 ms