文章目录
- Java设计模式之原型模式
- 前言
- 一、原型模式
- 二、适用场景
- 三、使用
- 1. 浅克隆
- 地址类
- 用户类
- 测试
- 2. 深克隆
- 地址类
- 用户类
- 测试
- 3. 区别
- 总结
- 优点
- 缺点
前言
- 掌握原型模式的应用场景
- 掌握原型模式浅克隆和深克隆的写法
- 了解克隆是如何破环单例的
- 了解原型模式的优、缺点
一、原型模式
- 原型模式(Prototype Pattern)是指原型实例指定创建对象的种类,并且通过拷贝这些原型创建新的对象。
- 调用者不需要知道任何创建细节,不调用构造函数。
- 类初始化消耗资源较多。
- new产生的一个对象需要非常繁琐的过程(数据准备、访问权限等)。
- 构造函数比较复杂。
- 循环体中生产大量对象时。
@Data
@Accessors(chain = true)
public class Address {
private String province;
private String municipality;
private String region;
}
用户类
@Data
public class User implements Cloneable {
private String userName;
private Address address;
@Override
protected User clone() {
try {
return (User) super.clone();
} catch (CloneNotSupportedException e) {
e.printStackTrace();
}
return null;
}
}
测试
public static void main(String[] args) {
User user1 = new User();
user1.setUserName("张三");
user1.setAddress(new Address().setProvince("甘肃省").setMunicipality("兰州市").setRegion("七里河区"));
User clone = user1.clone();
System.out.println(user1);
System.out.println(clone);
System.out.println(user1 == clone); // false
System.out.println(user1.getAddress() == clone.getAddress()); // true 引用的同一个对象,修改其中一个用户的地址会影响到另一个用户的地址
}
2. 深克隆
@Data
@Accessors(chain = true)
public class Address implements Serializable {
private String province;
private String municipality;
private String region;
}
用户类
@Data
public class User implements Cloneable, Serializable {
private String userName;
private Address address;
@Override
protected User clone() {
try {
ByteArrayOutputStream bos = new ByteArrayOutputStream();
ObjectOutputStream oos = new ObjectOutputStream(bos);
oos.writeObject(this);
ByteArrayInputStream bis = new ByteArrayInputStream(bos.toByteArray());
ObjectInputStream ois = new ObjectInputStream(bis);
return (User) ois.readObject();
} catch (IOException e) {
e.printStackTrace();
} catch (ClassNotFoundException e) {
e.printStackTrace();
}
return null;
}
}
测试
public static void main(String[] args) {
User user1 = new User();
user1.setUserName("张三");
user1.setAddress(new Address().setProvince("甘肃省").setMunicipality("兰州市").setRegion("七里河区"));
User clone = user1.clone();
System.out.println(user1);
System.out.println(clone);
System.out.println(user1 == clone);
System.out.println(user1.getAddress() == clone.getAddress());
}
3. 区别
- 数据拷贝后两者之间是否有关联。
- 改变一个值是否会影响到另一个数值变化。
总结 优点
- 性能优良,Java自带原型模式是基于内存二进制流的拷贝,比直接new一个对象性能上提升了许多。
- 可以使用深克隆方式保存对象的状态,使用原型模式将对象复制一份并将其状态保存起来,简化了创建过程。
- 必须配备克隆(或者可拷贝)方法
- 当对已有类进行改造的时候,需要修改代码,违反了开闭原则。
- 深拷贝、浅拷贝需要运用得当。



