SDSU CS 635 Advanced Object-Oriented Design & Programming
Spring Semester, 2001
Factory Method & Prototype
Previous    Lecture Notes Index    Next    
© 2001, All Rights Reserved, SDSU & Roger Whitney
San Diego State University -- This page last updated 07-Mar-01

Contents of Doc 9, Factory Method & Prototype


References

Design Patterns: Elements of Reusable Object-Oriented Software , Gamma, Helm, Johnson, Vlissides, Addison-Wesley, 1995, pp. 107-126

The Design Patterns Smalltalk Companion, Alpert, Brown, Woolf, 1998, pp. 63-89

Doc 9, Factory Method & Prototype Slide # 2

Factory Method


A template method for creating objects

Example - Maze Game

Classes for Mazes




Now a maze game has to make a maze


Doc 9, Factory Method & Prototype Slide # 3
Maze Class Version 1
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 );
      
      etc.
      
      return aMaze;
      }
   }



Doc 9, Factory Method & Prototype Slide # 4
How do we make other Mazes?

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 );
      
      etc.

Note the amount of cut and paste!


Doc 9, Factory Method & Prototype Slide # 5
How do we make other Mazes?

Use 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() { return new Door(); }
   
   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 );
      
      etc
      
      return aMaze;
      }
   }


Doc 9, Factory Method & Prototype Slide # 6
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(); 
      }


Doc 9, Factory Method & Prototype Slide # 7

Applicability


Use when





Doc 9, Factory Method & Prototype Slide # 8

Consequences







Doc 9, Factory Method & Prototype Slide # 9

Implementation

Two Major Varieties



   abstract class MazeGame
      {
      public Maze makeMaze();
      public Room makeRoom(int n );
      public Wall makeWall();
      public Door makeDoor();
      etc.
      }
   
   class MazeGame
      {
      public:
         virtual Maze* makeMaze() = 0;
         virtual Room* makeRoom(int n ) = 0;
         virtual Wall* makeWall() = 0;
         virtual Door* makeDoor() = 0;


See examples on previous slides


Doc 9, Factory Method & Prototype Slide # 10
Implementation - Continued

Parameterized Factory Methods


Let the factory method return multiple products

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();
      }

class GenericBrand extends Hershey
   {
   public Candy makeChocolateStuff( CandyType id )
      {
      if ( id == M&Ms ) return new Flupps();
      if ( id == Milk ) return new MilkChocolate();
      return super.makeChocolateStuff();
      }
   }
   


Doc 9, Factory Method & Prototype Slide # 11

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;


Doc 9, Factory Method & Prototype Slide # 12
Java forName and Factory methods

With Java's reflection you can use a Class or a String to specify which type of object to create

Using a string replaces compile checks with runtime errors


class Hershey 
   {
   private String chocolateType;
   public Hershey( String chocolate )
      {
      chocolateType = chocolate;
      }
   public Candy makeChocolateStuff( )
      {
      Class candyClass =  Class.forName( chocolateType );
      return (Candy) candyClass.newInstance();
      }
Hershey theBest = new Heshsey( "SpecialRich" );



Doc 9, Factory Method & Prototype Slide # 13
Clients Can Use Factory Methods

class CandyStore
   {
   Hershey supplier;
   public restock()
      {
      blah
      if ( chocolateStock.amount() < 10 )
         {
         chocolateStock.add( 
            supplier.makeChocolateStuff() );
         }
   blah


Doc 9, Factory Method & Prototype Slide # 14

Prototype

Intent


Specify the kinds of objects to create using a prototypical instance, and create new objects by copying this prototype


Applicability


Use the Prototype pattern when




It may be easier to have the proper number of prototypes and clone them rather than instantiating the class manually each time



Doc 9, Factory Method & Prototype Slide # 15

Implementation/Sample Code

Simple Example

class Prototype
   {
   public Prototype clone() 
      {
      code to make a copy of current Prototype object
      return clone;
      }
      // add what ever else you want the class to do
   }
class Protoplasm extends  Prototype
   {
   public Prototype clone() 
      {
      code to make a copy of current Protoplasm object
      return clone;
      }
   // add more other stuff
   }
ClientCodeMethod( Prototype example )
   {
   Prototype myCopy = example.clone();
   // do some work using myCopy
   }


Doc 9, Factory Method & Prototype Slide # 16

Cloning Issues

How to in C++ - Copy Constructors

class Door 
   {
   public:
      Door();
      Door( const Door&);
      virtual Door* clone() const;
      virtual void Initialize( Room*, Room* );
      // stuff not shown
   private:
      Room* room1;
      Room* room2;
   }
Door::Door ( const Door& other ) //Copy constructor
   {
   room1 = other.room1;
   room2 = other.room2;
   }
Door* Door::clone()  const 
   {
   return new Door( *this );
   }



Doc 9, Factory Method & Prototype Slide # 17
How to in Java - Object clone()

protected Object clone() throws CloneNotSupportedException

A bitwise clone of the current object is created

Returns:
A clone of this Object.

Throws: OutOfMemoryError
If there is not enough memory.

Throws: CloneNotSupportedException
Object explicitly does not want to be cloned, or it does not support the Cloneable interface.

class Door implements Cloneable 
   {
   public void Initialize( Room a, Room b) 
      { room1 = a; room2 = b; }
   public Object clone() throws
                CloneNotSupportedException
      {
      return super.clone();
      }
   Room room1;
   Room room2;
   }


Doc 9, Factory Method & Prototype Slide # 18

Shallow Copy Verse Deep Copy


Original Objects


Shallow Copy




Doc 9, Factory Method & Prototype Slide # 19
Shallow Copy Verse Deep Copy

Original Objects


Deep Copy




Doc 9, Factory Method & Prototype Slide # 20
Template or Boilerplate Objects

May wish to specify how an object differs from a standard configuration

Example: Insurance policy

Insurance agents start with a standard policy and customize it


Two basic strategies:





Doc 9, Factory Method & Prototype Slide # 21

Consequences








Implementation Issues






Copyright ©, All rights reserved.
2001 SDSU & Roger Whitney, 5500 Campanile Drive, San Diego, CA 92182-7700 USA.
OpenContent license defines the copyright on this document.

Previous    visitors since 07-Mar-01    Next