The prototype pattern is a creational design pattern used in software development when the type of objects to create is determined by a prototypical instance, which is cloned to produce new objects. This pattern is used to 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 a system should be independent of how its products are created, composed, and represented and
  • When the classes to instantiate are specified at run-time to avoid building a class hierarchy of factories that parallels the class hierarchy of products or
  • When instances of a class can have one of only a few different combinations of state. It may be easier to have the proper number of prototypes and clone them rather than instantiating the class manually each time

Solution:

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
}

Prototype Implementation in Java

Java provides clone() object as given below:

protected Object clone() throws CloneNotSupportedException

It creates a clone of the object. A new instance is allocated and a bitwise clone of the current object is placed in the new object. It returns a clone of this Object and throws OutOfMemoryError. If there is not enough memory it 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;
}

Shallow Copy Vs Deep Copy

Example of Prototype

JavaServer handles the network connection.

Algorithm:

  1. Wait for client to connect
  2. Open connection
  3. Create IO streams to client
  4. Create Server Engine to handle request
  5. Let engine handle the request

Variations:

JavaServer will want to multiple copies of server engine to handle more than one client at a time
Would like to write JavaServer just once and use it for all possible different server engines

JavaSever With Factory Method for a DateServer

class JavaServer {
   ServerSocket acceptor;
   public JavaServer( int portNumber ) {
      acceptor = new ServerSocket( portNumber );
   }
   public void run() {
      while (true) {
         Socket client = acceptor.accept();
         InputStream cin = client.getInputStream();
         OutputStream cout = client.getOutputStream();
         processClientRequest( cin, cout );
      }
   }
   private void processClientRequest( InputStream cin, OutputStream cout ) {
      DateServer handler = new DateServer( cin, cout);
      handler.processClientRequest();
   }
}
class AirlineReservationJavaServer extends JavaServer {
   public AirlineReservationServer( int portNumber ) {
      super( portNumber );
   }

   private void processClientRequest( InputStream cin, OutputStream cout ) { AirlineReservation handler;
      handler = new AirlineReservation( cin, cout );
      handler.processClientRequest();
   }
}
  • Program to an interface, not an implementation
  • Use abstract classes (and/or interfaces in Java) to define common interfaces for a set of classes
  • Declare variables to be instances of the abstract class not instances of particular classes

The Interface

interface ServerEngine {

public void processClientRequest(InputStream in, OutputStream out);

}

JavaServer with Factory Method

abstract class JavaServer {
   ServerSocket acceptor;
   public JavaServer( int portNumber ) {
      acceptor = new ServerSocket( portNumber );
   }
   public void run() {
      while (true) {
         Socket client = acceptor.accept();
         InputStream cin = client.getInputStream();
         OutputStream cout = client.getOutputStream();
         ServerEngine requestHandler = makeServerEngine();
         requestHandler.processClientRequest( cin, cout );
       }
   }
   abstract protected ServerEngine makeServerEngine();
}
interface ServerEngine {
   public ServerEngine clone( InputStream in, OutputStream out );
   public void processClientRequest();
}
class JavaServer {
   ServerSocket acceptor;
   ServerEngine serverPrototype;
   public JavaServer( int portNumber, ServerEngine aCopy) {
      acceptor = new ServerSocket( portNumber );
      serverPrototype = aCopy;
   }
   public void run() {
      while (true) {
         Socket client = acceptor.accept();
         InputStream cin = client.getInputStream();
         OutputStream cout = client.getOutputStream();
         ServerEngine requestHandler = serverPrototype.clone( cin, cout);
         requestHandler.processClientRequest( cin, cout );
       }
   }
}
class DriverProgram {
   public static void main( String args[] ) {
      ServerEngine aPrototype = new DateServer();
      JavaServer networkListener;
      networkListener = new JavaServer( 6666, aPrototype );
      networkListener.run();
   }
}

Consequences

  • Adding and removing products at run-time
  • Specifying new objects by varying values
  • Specifying new objects by varying structure
  • Reducing subclassing (from factory method)
  • Configuring an application with classes dynamically
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.