原型模型:用于创建重复对象,同时保证性能。
这种模式实现一个原型接口,用于创建对象的克隆,当直接创建对象的代价比较大,则可以采用这种模式。例如:一个对象需要高代价的数据库操作之后被创建,这时可以缓存该对象,在下次请求时返回其克隆,不必在进行高代价的数据库操作。
下面将创建一个抽象类Pizza,再定义类PizzaCache,该类把Pizza对象存储在一个Hashtable中,并在请求的时候返回它们的克隆。
PrototypePatternDemo类使用PizzaCache来获取Pizza对象。
Pizza.java
public abstract class Pizza implements Cloneable { private String name; abstract void order(); public String getName() { return name; } public void setName(String name) { this.name = name; } public Object clone() { Object clone = null; try { clone = super.clone(); } catch (CloneNotSupportedException e) { e.printStackTrace(); } return clone; } }
CheesePizza.java
public class CheesePizza extends Pizza { public CheesePizza() { name = "CheesePizza"; } public void order() { System.out.println("Book a CheesePizza"); } }
VeggiePizza.java
public class VeggiePizza extends Pizza { public VeggiePizza() { name = "VeggiePizza"; } public void order() { System.out.println("Book a VeggiePizza"); } }
public class PizzaCache { private static Hashtable<String, Pizza> PizzaMap = new Hashtable<String, Pizza>(); public static Pizza getPizza(String pizzaName) { Pizza cache = PizzaMap.get(pizzaName); return (Pizza) cache.clone(); } public static void loadCache() { CheesePizza cheesePizza = new CheesePizza(); PizzaMap.put(cheesePizza.getName(), cheesePizza); VeggiePizza veggiePizza = new VeggiePizza(); PizzaMap.put(veggiePizza.getName(), veggiePizza); } }
public class PrototypePatternDemo { public static void main(String[] args) { PizzaCache.loadCache(); Pizza pizza1 = (Pizza) PizzaCache.getPizza("CheesePizza"); System.out.println("Pizza:" + pizza1.getName()); Pizza pizza2 = (Pizza) PizzaCache.getPizza("VeggiePizza"); System.out.println("Pizza:" + pizza2.getName()); } }
与通过对一个类进行实例化来构造新对象不同的是,原型模式是通过拷贝一个现有对象生成新对象的。
拷贝的两种方式:
浅复制:将一个对象复制后,基本数据类型的变量都会重新创建,而引用类型,指向的还是原对象所指向的。
深复制:将一个对象复制后,不论是基本数据类型还有引用类型,都是重新创建的。简单来说,就是深复制进行了完全彻底的复制,而浅复制不彻底。
上面的例子实现的是浅拷贝。
浅拷贝实现 Cloneable,重写,深拷贝是通过实现 Serializable 读取二进制流。