Factory Method design pattern defines an interface for creating an object, but let subclasses decide which class to instantiate. Like other creational patterns, it deals with the problem of creating objects (products) without specifying the exact class of object that will be created. More generally, the term Factory Method is often used to refer to any method whose main purpose is to create objects.

Structure

Example: Maze Game

Maze Class Version 1

Now a maze game has to make a maze, so we might have something like:

class MazeGame {
   public Maze createMaze() {
      Maze aMaze = new Maze();
      Room r1 = new Room( 1 ); Room r2 = new Room( 2 );
      Door theDoor = new Door( r1, r2);
      aMaze.addRoom( r1 ); aMaze.addRoom( r2 );

      r1.setSide( North, new Wall() ); r1.setSide( East, theDoor );
      r1.setSide( South, new Wall() ); r1.setSide( West, new Wall() );
      r2.setSide( North, new Wall() ); r2.setSide( East, new Wall() );
      r2.setSide( South, new Wall() ); r2.setSide( West, theDoor );
      return aMaze;
   }
}

Problem

How do we make Other Mazes?

Solution 1:

Subclass MazeGame, override createMaze

class BombedMazeGame extends MazeGame {
   public Maze createMaze() {
      Maze aMaze = new Maze();
      Room r1 = new RoomWithABomb( 1 );
      Room r2 = new RoomWithABomb( 2 );
      Door theDoor = new Door( r1, r2);
      aMaze.addRoom( r1 ); aMaze.addRoom( r2 );
      r1.setSide( North, new BombedWall() );
      r1.setSide( East, theDoor );
      r1.setSide( South, new BombedWall() );
      r1.setSide( West, new BombedWall() );

Note the amount of copy and paste!

Solution 2:

Factory Method

class MazeGame {
   public Maze makeMaze() { return new Maze(); }
   public Room makeRoom(int n ) { return new Room( n ); }
   public Wall makeWall() { return new Wall(); }
   public Door makeDoor(Room r1, Room r2) { return new Door(r1, r2); }

   public Maze CreateMaze() {
      Maze aMaze = makeMaze();
      Room r1 = makeRoom( 1 );
      Room r2 = makeRoom( 2 );
      Door theDoor = makeDoor( r1, r2);
      aMaze.addRoom( r1 );
      aMaze.addRoom( r2 );
      r1.setSide( North, makeWall() );
      r1.setSide( East, theDoor );
      r1.setSide( South, makeWall() );
      r1.setSide( West, makeWall() );

      r2.setSide( North, makeWall() );
      r2.setSide( East, makeWall() );
      r2.setSide( South, makeWall() );
      r2.setSide( West, theDoor );

      return aMaze;
   }
}

Now subclass MazeGame override make methods. CreateMaze method stays the same

class BombedMazeGame extends MazeGame {
   public Room makeRoom(int n ) {
      return new RoomWithABomb( n );
   }
   public Wall makeWall() {
      return new BombedWall();
   }

Implementation Varieties of Factory Method

There are two major varieties of

1. Creator class is an abstract class:

Does not provide default implementation of factory methods

abstract class MazeGame {
   public Maze makeMaze();
   public Room makeRoom(int n );
   public Wall makeWall();
   public Door makeDoor(); 
}

2. Creator is a concrete class:

Provides a default implementation for the factory method. Create objects in a separate operation so that subclasses can override the way they’re created.

class MazeGame {
   public Maze makeMaze() { return new Maze(); }
   public Room makeRoom(int n ) { return new Room( n ); }
   public Wall makeWall() { return new Wall(); }
   public Door makeDoor(Room r1, Room r2) { return new Door(r1, r2);
}

Parameterized Factory Methods

A variation on the pattern

  • Lets the factory method create multiple kinds of products
  • Takes a parameter that identifies the kind of object to create
  • All the objects factory method creates will share the Product Interface

C++ Templates to Avoid Subclassing

 

template <class ChocolateType>
class Hershey {
   public: virtual Candy* makeChocolateStuff( );
}

template <class ChocolateType>
Candy* Hershey<ChocolateType>::makeChocolateStuff( ) {
   return new ChocolateType;
}

Hershey<SpecialRich> theBest;
class Hershey {
   public Candy makeChocolateStuff( CandyType id ) {
      if ( id == MarsBars ) return new MarsBars();
      if ( id == M&Ms ) return new M&Ms();
      if ( id == SpecialRich ) return new SpecialRich();
      return new PureChocolate();
 }
Tagged with: Design PatternJAVAObject Oriented
 

Leave a Reply

Your email address will not be published.

You may use these HTML tags and attributes: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong>

 

Looking for something?

Use the form below to search the site:


Still not finding what you're looking for? Drop a comment on a post or contact us so we can take care of it!

Related News Feeds

Set your Twitter account name in your settings to use the TwitterBar Section.