首页 > 代码库 > 深入浅出设计模式 ------ 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(原型模式)