首页 > 代码库 > 深入浅出设计模式 ------ Prototype(原型模式)
深入浅出设计模式 ------ Prototype(原型模式)
一. 定义 用原型实例指定创建对象的种类、 并且通过拷贝这些原型创建新的对象。
二. 结构
三. 参与者
Prototype : 克隆自身的接口(如代码实现中的FruitPrototype)
PrototypeTool : 管理Prototype的工具类, 存储原型复制自身到数据接口(如FruitTool)
ConcretePrototype : 实现一个克隆自身的操作(如ConcteteFruitPrototype)
Client : 测试类
四. 适用性
-- 多用于创建复杂的或者耗时的实例,因为这种情况下,复制一个已经存在的实例使程序运行更高效
-- 创建值相等,只是命名不一样的同类数据
-- 实例化的类是在运行时加载, 例如动态加载
-- 避免创建一个与产品类层次平行的工厂类层次(即避免像工厂方法一样, 可能会创建太多子类)
五. 代码实现
原型接口: 对外提供获取原型拷贝的入口
package com.wenniuwuren.prototype; /** * 原型接口 * @author wenniuwuren * */ public interface FruitPrototype{ public abstract FruitPrototype cloneNew() throws CloneNotSupportedException; }
package com.wenniuwuren.prototype; /** * 原型具体实现 * @author wenniuwuren * */ public class ConcteteFruitPrototype implements FruitPrototype, Cloneable{ private String size; private String color; public ConcteteFruitPrototype(String size, String color) { this.size = size; this.color = color; } // 克隆 public FruitPrototype cloneNew() throws CloneNotSupportedException { return (FruitPrototype) super.clone(); } // 方便打印 public void display(String colorname) { System.out.println(colorname+"的大小是: "+size+" 颜色是:"+color); } }
package com.wenniuwuren.prototype; import java.util.HashMap; /** * 原型管理类 * @author wenniuwuren * */ public class FruitTool { private HashMap<String, FruitPrototype> fruits = new HashMap<String, FruitPrototype>(); public void put(String key, FruitPrototype fruitPrototype) { fruits.put(key, fruitPrototype); } public FruitPrototype get(String key) { return fruits.get(key); } }
测试类:
package com.wenniuwuren.prototype; public class Client { public static void main(String[] args) throws CloneNotSupportedException { FruitTool fruitTool = new FruitTool(); // 初始化水果的大小和颜色 fruitTool.put("Apple", new ConcteteFruitPrototype("Middle", "Green")); fruitTool.put("Watermelon", new ConcteteFruitPrototype("Large", "Red")); fruitTool.put("Lemon", new ConcteteFruitPrototype("Small", "Yellow")); String fruitName = "Apple"; ConcteteFruitPrototype concteteFruitPrototype = (ConcteteFruitPrototype) fruitTool .get(fruitName).cloneNew(); concteteFruitPrototype.display(fruitName); fruitName = "Lemon"; concteteFruitPrototype = (ConcteteFruitPrototype) fruitTool.get( fruitName).cloneNew(); concteteFruitPrototype.display(fruitName); } }
运行结果:
Apple的大小是: Middle 颜色是:Green Lemon的大小是: Small 颜色是:Yellow
以上代码是利用JDK自带的clone()实现Prototype模式, 这里面的clone()使用的是浅克隆。
浅克隆 : 只负责克隆按值传递的数据(比如基本数据类型、String类型),而不复制它所引用的对象,既所有的对其他对象的引用都仍然指向原来的对象(如自定义类LeafReferrence, 在clone()后LeafReferrence引用只有唯一的一份,改变复制前的索引和改变复制后的索引所引起的都是全局的改变, 即对象引用不被复制, JVM内存模型中仅有一份)。
深克隆 : 则把前克隆所没复制的引用复制了一份, 跟基本数据类型和String一样都是新的一份, 复制前后的是独立的。(天色已晚, 深克隆稍后补上)
参考资料:
Wikipedia : 原型模式
《设计模式 : 可复用面向对象软件的基础》
深入浅出设计模式 ------ Prototype(原型模式)