Concepts
- Avoids costly creation
- Avoids subclassing
- Typically doesn't use "new"
- Often utilizes an Interface
- Usually implemented with a Registry
- Example: java.lang.Object#clone()
------------------------------------------------------------
Design
- Clone/Cloneable
- Avoids keyword "new"
- Although a copy, each instance unique
- Costly construction not handled by client
- Can still utilize parameters for construction
- Shallow VS Deep Copy
------------------------------------------------------------
Everyday Example - Object Clone
package com.pattern.prototype;
import java.util.List;
public class Statement implements Cloneable {
private String sql;
private List<String> parameters;
private Record record;
public Statement(String sql, List<String> parameters, Record record) {
this.sql = sql;
this.parameters = parameters;
this.record = record;
}
public Statement clone() {
try {
return (Statement) super.clone();
} catch (CloneNotSupportedException e) {
e.printStackTrace();
}
return null;
}
public String getSql() {
return sql;
}
public List<String> getParameters() {
return parameters;
}
public Record getRecord() {
return record;
}
}
package com.pattern.prototype;
import java.util.ArrayList;
import java.util.List;
public class PrototypeEverydayDemo {
public static void main(String[] args) {
String sql = "select * from movies where title = ?";
List<String> parameters = new ArrayList<String>();
parameters.add("Star wars");
Record record = new Record();
Statement statement = new Statement(sql, parameters, record);
Statement cloneStatement = statement.clone();
System.out.println(statement);
System.out.println(statement.getSql());
System.out.println(statement.getParameters());
System.out.println(statement.getRecord());
System.out.println(" ------------");
System.out.println(cloneStatement);
System.out.println(cloneStatement.getSql());
System.out.println(cloneStatement.getParameters());
System.out.println(cloneStatement.getRecord());
}
}
------------------------------------------------------------
Exercise Prototype
- Create Prototype
- Demonstrate shallow copy
- Create with a Registry
Demo: Prototype
1.实体类
2.注册类
3.Demo类,main方法
package com.pattern.prototype;
public abstract class Item implements Cloneable {
private String title;
private double price;
@Override
protected Object clone() throws CloneNotSupportedException {
return super.clone();
}
public String getTitle() {
return title;
}
public void setTitle(String title) {
this.title = title;
}
public double getPrice() {
return price;
}
public void setPrice(double price) {
this.price = price;
}
}
package com.pattern.prototype;
public class Movie extends Item {
private String runtime;
public String getRuntime() {
return runtime;
}
public void setRuntime(String runtime) {
this.runtime = runtime;
}
}
package com.pattern.prototype;
public class Book extends Item {
private int numberOfPages;
public int getNumberOfPages() {
return numberOfPages;
}
public void setNumberOfPages(int numberOfPages) {
this.numberOfPages = numberOfPages;
}
}
package com.pattern.prototype;
import java.util.HashMap;
import java.util.Map;
public class Registry {
private Map<String, Item> items = new HashMap<String, Item>();
public Registry() {
loadItems();
}
public Item createItem(String type) {
Item item = null;
try {
item = (Item) items.get(type).clone();
} catch (CloneNotSupportedException e) {
e.printStackTrace();
}
return item;
}
private void loadItems() {
Movie movie = new Movie();
movie.setTitle("Basic Movie");
movie.setPrice(24.99);
movie.setRuntime("2 hours");
items.put("Movie", movie);
Book book = new Book();
book.setTitle("Basic Book");
book.setPrice(19.99);
book.setNumberOfPages(11);
items.put("Book", book);
}
}
package com.pattern.prototype;
public class PrototypeDemo {
public static void main(String[] args) {
Registry registry = new Registry();
Movie movie = (Movie) registry.createItem("Movie");
Movie otherMovie = (Movie) registry.createItem("Movie");
System.out.println(movie);
System.out.println(movie.getTitle());
System.out.println(movie.getPrice());
System.out.println(movie.getRuntime());
System.out.println("---------------");
System.out.println(otherMovie);
System.out.println(otherMovie.getTitle());
System.out.println(otherMovie.getPrice());
System.out.println(otherMovie.getRuntime());
}
}
------------------------------------------------------------
Pitfalls
- Sometimes not clear when to use
- Used with other patterns (Registry)
- Shallow VS Deep Copy
------------------------------------------------------------
Contrast
Prototype
- Lighter weight construction(Copy Constructor or Clone)
- Shallow or Deep
- Copy of itself
Factory
- Flexible Objects(Multiple constructors)
- Concrete Instance
- Fresh Instance
------------------------------------------------------------
Prototype Summary
- Guarantee unique instance
- Often refactored in
- Can help with performance issues
- Don't always jump to a Factory
-------------------------------------------------------------
Factory Method Pattern
http://blog.csdn.net/u012596785/article/details/79511031