Working With Design Patterns: Prototype, Page 2
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);
}
}
0 Comments (click to add your comment)
Networking Solutions
