原型模式的使用场景
当创建一个新对象的成本比较大,则可以对原对象进行拷贝使用,这样可以节省创建对象的时间。比如创建对象的数据需要从RPC、数据库、文件系统等慢速IO中获取的时候可以使用这种原型模式。
原型模式示例
原型模式有两种方法,一种叫[[#浅拷贝]] ,另一种叫[[#深拷贝]]
浅拷贝
浅拷贝只会拷贝原对象的地址,新对象和原对象还是同一个对象。
@DisplayName("浅拷贝")
@Test
public void lightCloneTest() {
HashMap<String, String> originMap = new HashMap<>();
originMap.put("1", "test1");
originMap.put("2", "test2");
originMap.put("3", "test3");
System.out.println(originMap);
System.out.println("originMap地址为:" + originMap.hashCode());
Map<String, String> newMap = (Map<String, String>) originMap.clone();
System.out.println(newMap);
System.out.println("newMap地址为:" +newMap.hashCode());
}
运行结果
{1=test1, 2=test2, 3=test3}
originMap地址为:330754450
{1=test1, 2=test2, 3=test3}
newMap地址为:330754450
深拷贝
深拷贝会复制原数据本身,会得到一份完完整整的独立对象。深拷贝有两种方法,一种是[[#深拷贝-递归拷贝]];另一种是[[#深拷贝-序列化]]。
深拷贝-递归拷贝
递归拷贝对象直到对象只包含基础数据类型
@DisplayName("深拷贝,递归拷贝对象直到最后要拷贝的对象只包含基础数据类型")
@Test
public void deepCloneTest1() {
User user1 = new User();
user1.setUserId(1);
User user2 = new User();
user2.setUserId(2);
User user3 = new User();
user3.setUserId(3);
User user4 = new User();
user4.setUserId(4);
HashMap<String, User> originMap = new HashMap<>();
originMap.put("1", user1);
originMap.put("2", user2);
originMap.put("3", user3);
System.out.println(originMap);
Map<String,User> newMap = new HashMap<>();
for(Map.Entry<String, User> entry : originMap.entrySet()) {
User tempUser = new User();
tempUser.setUserId(entry.getValue().getUserId());
newMap.put(entry.getKey(), tempUser);
}
System.out.println(newMap);
newMap.get("1").setUserId(4);
System.out.println("修改newMap内容后");
System.out.println(originMap);
System.out.println(newMap);
}
运行结果
{1=User{userId=1}, 2=User{userId=2}, 3=User{userId=3}}
{1=User{userId=1}, 2=User{userId=2}, 3=User{userId=3}}
修改newMap内容后
{1=User{userId=1}, 2=User{userId=2}, 3=User{userId=3}}
{1=User{userId=4}, 2=User{userId=2}, 3=User{userId=3}}
深拷贝-序列化
对对象进行序列化后再反序列化后获得的对象。
@DisplayName("序列化来进行深拷贝")
@Test
public void deepCloneTest2() throws IOException, ClassNotFoundException {
User user1 = new User();
user1.setUserId(1);
User user2 = new User();
user2.setUserId(2);
User user3 = new User();
user3.setUserId(3);
User user4 = new User();
user4.setUserId(4);
HashMap<String, User> originMap = new HashMap<>();
originMap.put("1", user1);
originMap.put("2", user2);
originMap.put("3", user3);
System.out.println(originMap);
HashMap<String,User> newMap = (HashMap<String,User>) deepCopy(originMap);
newMap.get("1").setUserId(4);
System.out.println("修改newMap内容后");
System.out.println(originMap);
System.out.println(newMap);
}
对一个[[对象序列化]]的方法
public Object deepCopy(Object object) throws IOException, ClassNotFoundException {
ByteArrayOutputStream bo = new ByteArrayOutputStream();
ObjectOutputStream oo = new ObjectOutputStream(bo);
oo.writeObject(object);
ByteArrayInputStream bi = new ByteArrayInputStream(bo.toByteArray());
ObjectInputStream oi = new ObjectInputStream(bi);
return oi.readObject();
}
运行结果
{1=User{userId=1}, 2=User{userId=2}, 3=User{userId=3}}
修改newMap内容后
{1=User{userId=1}, 2=User{userId=2}, 3=User{userId=3}}
{1=User{userId=4}, 2=User{userId=2}, 3=User{userId=3}}