January 19, 2020
Hot Topics:

Working With Design Patterns: Prototype

  • April 2, 2008
  • By Jeff Langr
  • Send Email »
  • More Articles »

The prototype pattern suggests that the catalog tell the prototype object (in this case, the Book object) to return a clone of itself. In other words, the Book class should do all the work. Adding the Movie type, in turn, suggests that the solution should be polymorphic.

A more robust and refactored solution that incorporates the notion of a prototype appears in Listings 4 (the tests) and 5 (the production code). Listing 6 shows the Material, Book, and Movie classes.

Listing 4: Tests to drive out use of prototype.

import static org.junit.Assert.*;

import java.util.*;
import org.junit.*;

public class CatalogTest {
   private Catalog catalog;

   public void initialize() {
      catalog = new Catalog();

   public void isEmptyOnCreation() {
      assertEquals(0, catalog.size());

   public void addNewBook() {
      final Book book = new Book("QA123", "author", "title",
                                 "1999", 1);
      assertEquals(1, catalog.size());
      List<Material> materials = catalog.get("QA123");
      assertEquals(1, materials.size());
      assertSame(book, materials.get(0));

   public void addNewCopyThrowsIfNoExistingCopy() {

   public void addCopyViaPrototype() {
      final Book book = new Book("QA123", "title", "author",
                                 "1999", 1);

      assertEquals(2, catalog.size());
      assertMaterialCopies("QA123", 2, book);

   public void addMovieCopyViaPrototype() {
      final Movie movie = new Movie("DD890", "Shining", "Kubrick",
                                    "2006", 1, Movie.Format.DVD);

      assertEquals(2, catalog.size());
      assertMovieCopies("DD890", 2, movie);

   private void assertMaterialCopies(String classification,
      int number, Material material) {
      List<Material> materials = catalog.get(classification);
      assertEquals(number, materials.size());

      for (int i = 0; i < number; i++) {
         Material copy = materials.get(i);
         assertEquals(material.getClass(), copy.getClass());
         assertEquals(material.getAuthor(), copy.getAuthor());
         assertEquals(material.getTitle(), copy.getTitle());
         assertEquals(material.getYear(), copy.getYear());
         assertEquals(i + 1, copy.getCopyNumber());

   private void assertMovieCopies(String classification,
                                  int number, Movie material) {
      assertMaterialCopies(classification, number, material);
      for (Material copy: catalog.get(classification))

Listing 5: A Catalog that uses the prototype pattern.

import java.util.*;

public class Catalog {
   private MultiMap<String, Material> materials =
      new MultiMap<String, Material>();

   public void addCopy(String classification) {
      List<Material> copies = materials.get(classification);
      if (copies.isEmpty())
         throw new NoExistingCopyException();

      materials.put(classification, copies.get(0).copy());

   public int size() {
      return materials.valuesSize();

   public void addNew(Material material) {
      materials.put(material.getClassification(), material);

   public List<Material> get(String classification) {
      return materials.get(classification);

Page 2 of 3

Enterprise Development Update

Don't miss an article. Subscribe to our newsletter below.

Thanks for your registration, follow us on our social networks to keep up-to-date