Tuesday, February 09, 2010

Design Patterns : Prototype pattern

The prototype pattern specifies the kind of objects to create using a prototypical instance, and creates new objects by copying the prototype. A clone method is available in the class which can be used to create new objects of the same kind.

The pattern consists of a prototype - an interface of the cloneable classes. A ConcretePrototype implements the clone operations and a client actually clones the prototype instance to use the clones as new objects.

Simple examples

PHP
abstract class BookPrototype
{
  protected $title;
  protected $topic;
  abstract function __clone();
  function getTitle()
  {
    return $this->title;
  }
  function setTitle($titleIn)
  {
    $this->title = $titleIn;
  }
  function getTopic()
  {
    return $this->topic;
  }
}

class PHPBookPrototype extends BookPrototype
{
  function __construct()
  {
    $this->topic = 'PHP';
  }
  function __clone()
  {  }
}

class SQLBookPrototype extends BookPrototype
{
  function __construct()
  {
    $this->topic = 'SQL';
  }
  function __clone()
  {  }
}

echo("BEGIN \n");

$phpProto = new PHPBookPrototype();
$sqlProto = new SQLBookPrototype();

$book1 = clone $sqlProto;
$book1->setTitle('SQL Book prototype');
echo('Book 1 topic: '.$book1->getTopic()."\n");
echo('Book 1 title: '.$book1->getTitle()."\n");

$book2 = clone $phpProto;
$book2->setTitle('PHP Book prototype');
echo('Book 2 topic: '.$book2->getTopic()."\n");
echo('Book 2 title: '.$book2->getTitle()."\n");

$book3 = clone $sqlProto;
$book3->setTitle('SQL Book prototype II');
echo('Book 3 topic: '.$book3->getTopic()."\n");
echo('Book 3 title: '.$book3->getTitle()."\n");

echo("END\n");

Output:

BEGIN 
Book 1 topic: SQL
Book 1 title: SQL Book prototype
Book 2 topic: PHP
Book 2 title: PHP Book prototype
Book 3 topic: SQL
Book 3 title: SQL Book prototype II
END

Java :

public class proto 
{
  interface Xyz 
  {
    Xyz cloan();
  }

  static class Tom implements Xyz 
  {
    public Xyz cloan()    
    {
      return new Tom();
    }
    public String toString() 
    {
      return "tom prototype";
    }
  }

  static class Dick implements Xyz 
  {
    public Xyz    cloan()    
    {
      return new Dick();
    }
    public String toString() 
    {
      return "dick prototype";
    }
  }

  static class Harry implements Xyz 
  {
    public Xyz    cloan()    
    {
      return new Harry();
    }
    public String toString() 
    {
      return "harry prototype";
    }
  }

  static class Factory 
  {
    private static java.util.Map prototypes = new java.util.HashMap();
    static 
    {
      prototypes.put( "tom",   new Tom() );
      prototypes.put( "dick",  new Dick() );
      prototypes.put( "harry", new Harry() );
    }
    public static Xyz makeObject( String s ) 
    {
      return ((Xyz)prototypes.get(s)).cloan();
    }
  }

  public static void main( String[] args ) 
  {
    for (int i=0; i < args.length; i++) 
    {
      System.out.println( Factory.makeObject( args[i] ) + "  " );
    }
  }
}

Output : 
$ java proto tom dick harry harry tomtom prototype  
dick prototype  
harry prototype  
harry prototype  
tom prototype 

No comments: