April 24, 2014
Hot Topics:
RSS RSS feed Download our iPhone app

Working With Design Patterns: Prototype, Page 2

  • 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;

   @Before
   public void initialize() {
      catalog = new Catalog();
   }

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

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

   @Test(expected=NoExistingCopyException.class)
   public void addNewCopyThrowsIfNoExistingCopy() {
      catalog.addCopy("QA123.4");
   }

   @Test
   public void addCopyViaPrototype() {
      final Book book = new Book("QA123", "title", "author",
                                 "1999", 1);
      catalog.addNew(book);
      catalog.addCopy("QA123");

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

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

      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.getClassification(),
                      copy.getClassification());
         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))
         assertEquals(material.getFormat(),
                      ((Movie)copy).getFormat());
   }
}

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



Comment and Contribute

 


(Maximum characters: 1200). You have characters left.

 

 


Sitemap | Contact Us

Rocket Fuel