设计模式
本系列文章均是博主原创,意在记录学习上的知识,同时一起分享学习心得。前言
本节介绍原型模式的概念、使用场景、实现方式。
一、概念
如果创建一个对象的成本比较大,而同一个类的不同对象之间差别不大(大部分字段相同),在这种情况下,我们可以利用对已有对象(原型)进行复制(拷贝)的方式来创建新对象,以达到节省创建时间的目的。这种基于原型来创建对象的方式叫做原型设计模式,简称原型模式。
二、实现方式
2.1 深拷贝
深拷贝不仅会复制索引,还会复制对象本身,得到的是一份完完全全独立的对象。所以深拷贝会更加耗时、耗费空间。
代码如下(示例):
public class Archetype {
private HashMap<String, SearchMessage> currentMap = new HashMap<>();
public void refresh() {
for (int i = 0; i < 5; i++) {
SearchMessage searchMessage = new SearchMessage();
searchMessage.setName(i + "");
searchMessage.setTimes(i);
currentMap.put(searchMessage.getName(), searchMessage);
}
System.out.println(currentMap);
// 深拷贝
HashMap<String, SearchMessage> deepCopy = deepCopy(currentMap);
System.out.println(deepCopy);
}
public HashMap<String, SearchMessage> deepCopy(HashMap<String, SearchMessage> copyedMap) {
HashMap<String, SearchMessage> deepCopy = new HashMap<>();
for (Map.Entry<String, SearchMessage> entry : copyedMap.entrySet()) {
SearchMessage value = entry.getValue();
SearchMessage newValue = new SearchMessage();
newValue.setName(value.getName());
newValue.setTimes(value.getTimes());
deepCopy.put(value.getName(), newValue);
}
return deepCopy;
}
}
@Test
public void test() {
Archetype archetype = new Archetype();
archetype.refresh();
}
2.2 浅拷贝
浅拷贝只会复制对象的地址,不会复制数据本身,得到的对象跟原始对象共享一份数据。
代码如下(示例):
public class LightArchetype {
private HashMap<String, SearchMessage> currentMap = new HashMap<>();
public void refresh() {
for (int i = 0; i < 5; i++) {
SearchMessage searchMessage = new SearchMessage();
searchMessage.setName(i + "");
searchMessage.setTimes(i);
currentMap.put(searchMessage.getName(), searchMessage);
}
System.out.println(currentMap);
// 原型模式,浅拷贝
HashMap<String, SearchMessage> temp = lightCopy(currentMap);
System.out.println(temp);
}
public HashMap<String, SearchMessage> lightCopy(HashMap<String, SearchMessage> copyedMap) {
return (HashMap<String, SearchMessage>) currentMap.clone();
}
}
@Test
public void lightTest() {
LightArchetype archetype = new LightArchetype();
archetype.refresh();
}
总结
如果要拷贝的对象是不可变对象,浅拷贝共享不可变对象是没问题的,但对于可变对象来说,浅拷贝得到的对象和原始对象会共享部分数据,就有可能出现数据被修改的风险,也就变得复杂得多。除非拷贝操作非常耗时,否则不要为了一点性能使用浅拷贝。