一、模式定义
用原型实例指定要创建对象的种类,并通过拷贝这些原型创建新的对象。
二、模式场景假设
此处结合23中设计模式记忆篇作出假设,不关心逻辑是否合理。柳岩在跳舞的时候烧伤了脸,再也回不到原来的型状。他就克隆一张脸。类图如下:
三、代码实现
1、创建一个类柳岩的脸
package com.pattern.prototype;
/**
* 建立一个类,代表柳岩的脸
* @author dgw
*
*/
public class LiuYanFace implements Cloneable{
//脸的颜色
private String color;
public LiuYanFace(){
//System.out.println("柳岩的脸");
}
public LiuYanFace(String color) {
super();
this.color = color;
}
public String getColor() {
return color;
}
public void setColor(String color) {
this.color = color;
}
//重新Object中的clone方法
@Override
protected LiuYanFace clone() throws CloneNotSupportedException {
return (LiuYanFace) super.clone();
}
}
2,测试代码
package com.pattern.prototype;
import org.junit.Test;
public class TestProtoType {
@Test
public void testPrototype() throws CloneNotSupportedException{
//创建100万对象需要 8.524s
//int i=0;
//while(i<1000000){
//LiuYanFace liuYanFace = new LiuYanFace();
//i++;
//}
//创建100万对象需要 8.220s
//int i=0;
//LiuYanFace liuYanFace = new LiuYanFace();
//while(i<1000000){
//LiuYanFace clone = liuYanFace.clone();
//i++;
//}
}
}
3、原型模式的注意事项
1)潜克隆对应用对象不进行拷贝。
package com.pattern.prototype;
import java.util.Map;
import org.junit.Test;
public class TestProtoType {
@Test
public void testPrototype() throws CloneNotSupportedException{
//创建100万对象需要 8.524s
//int i=0;
//while(i<1000000){
//LiuYanFace liuYanFace = new LiuYanFace();
//i++;
//}
//创建100万对象需要 8.220s
//int i=0;
//LiuYanFace liuYanFace = new LiuYanFace();
//while(i<1000000){
//LiuYanFace clone = liuYanFace.clone();
//i++;
//}
//原型对象
LiuYanFace liuYanFace = new LiuYanFace("白的");
//克隆对象
LiuYanFace clone = liuYanFace.clone();
clone.setColor("黑的");
//原型对象的颜色
System.out.println(liuYanFace.getColor());//白的
//克隆对象的颜色
System.out.println(clone.getColor());//黑的
//克隆对象的颜色
System.out.println(liuYanFace.map);
//{prototype=白的}
System.out.println(clone.map);
//{prototype=白的}
//修改克隆对象的map中颜色
clone.map.put("prototype", "黄的");
//见鬼了吗,怎么都改为黄色了,哈哈,这就是潜克隆。java偷懒了只克隆本对象,其对象内的数组、引用对象(String除外)都不拷贝。
System.out.println(liuYanFace.map);//黄的
System.out.println(clone.map);//黄的
}
}
2)深克隆,深拷贝。
package com.pattern.prototype;
import java.util.HashMap;
import java.util.Map;
import java.util.UUID;
/**
* 建立一个类,代表柳岩的脸
* @author dgw
*
*/
public class LiuYanFace implements Cloneable{
public Map map=new HashMap();
//脸的颜色
private String color;
public LiuYanFace(){
//System.out.println("柳岩的脸");
}
public LiuYanFace(String color) {
super();
this.color = color;
map.put("prototype", color);
}
public String getColor() {
return color;
}
public void setColor(String color) {
this.color = color;
}
//重新Object中的clone方法
@SuppressWarnings("unchecked")
@Override
protected LiuYanFace clone(){
LiuYanFace face=null;
try {
face=(LiuYanFace) super.clone();
//深度克隆
//face.map=(Map) ((HashMap) this.map).clone();
} catch (CloneNotSupportedException e) {
e.printStackTrace();
}
return face;
}
}
package com.pattern.prototype;
import java.util.Map;
import org.junit.Test;
public class TestProtoType {
@Test
public void testPrototype() throws CloneNotSupportedException{
//创建100万对象需要 8.524s
//int i=0;
//while(i<1000000){
//LiuYanFace liuYanFace = new LiuYanFace();
//i++;
//}
//创建100万对象需要 8.220s
//int i=0;
//LiuYanFace liuYanFace = new LiuYanFace();
//while(i<1000000){
//LiuYanFace clone = liuYanFace.clone();
//i++;
//}
//原型对象
LiuYanFace liuYanFace = new LiuYanFace("白的");
//克隆对象
LiuYanFace clone = liuYanFace.clone();
clone.setColor("黑的");
//原型对象的颜色
System.out.println(liuYanFace.getColor());//白的
//克隆对象的颜色
System.out.println(clone.getColor());//黑的
//克隆对象的颜色
System.out.println(liuYanFace.map);
//{prototype=白的}
System.out.println(clone.map);
//{prototype=白的}
//修改克隆对象的map中颜色
clone.map.put("prototype", "黄的");
System.out.println(liuYanFace.map);//白的
System.out.println(clone.map);//黄的
}
}
3)需要考培的属性不能使用final修饰。
四、优缺点分析
优点:性能良好、在内存中二进制流的拷贝,比new性能好。
缺点:在拷贝是构造函数不会执行,减少了约束。