设计模式之原型模式
原型模式指的是,从对象copy一个对象到另一个对象
- 浅拷贝: 类对象copy的时候使用的是地址,基础类型会进行数据拷贝
- 深拷贝:基础数据类型以及类对象都会进行数据copy
- spring创建对象的时候,可以选择单例,也可以选择原型模式
原始的copy方式:
需要拷贝的类
@Getter
@Setter
@NoArgsConstructor
@AllArgsConstructor
public class PrimitivePojo {
private String id;
private String name;
}
运行拷贝的类
public class Primitive {
public static void main(String[] args) {
PrimitivePojo primitivePojo = new PrimitivePojo("11", "张三");
PrimitivePojo prototypeType1 = new PrimitivePojo(primitivePojo.getId(), primitivePojo.getName());
PrimitivePojo prototypeType2 = new PrimitivePojo(primitivePojo.getId(), primitivePojo.getName());
PrimitivePojo prototypeType3 = new PrimitivePojo(primitivePojo.getId(), primitivePojo.getName());
PrimitivePojo prototypeType4 = new PrimitivePojo(primitivePojo.getId(), primitivePojo.getName());
PrimitivePojo prototypeType5 = new PrimitivePojo(primitivePojo.getId(), primitivePojo.getName());
}
}
优缺点分析:
优点:理解容易
缺点:后期增加属性的时候,需要改动代码,且增加一个必须改动拷贝类的代码,违法了opc原则
浅copy:
需要拷贝的类
@Getter
@Setter
@AllArgsConstructor
@NoArgsConstructor
@ToString
public class ShallowPojo implements Cloneable {
private String id;
private String name;
@Override
protected Object clone() throws CloneNotSupportedException {
return super.clone();
}
}
运行拷贝的类
public class Shallow {
public static void main(String[] args) throws CloneNotSupportedException {
ShallowPojo shallowPojo = new ShallowPojo("1", "张三");
System.out.println(shallowPojo);
ShallowPojo shallowPojo1 = (ShallowPojo) shallowPojo.clone();
ShallowPojo shallowPojo2 = (ShallowPojo) shallowPojo.clone();
ShallowPojo shallowPojo3 = (ShallowPojo) shallowPojo.clone();
ShallowPojo shallowPojo4 = (ShallowPojo) shallowPojo.clone();
ShallowPojo shallowPojo5 = (ShallowPojo) shallowPojo.clone();
System.out.println(shallowPojo1);
System.out.println(shallowPojo2);
System.out.println(shallowPojo3);
System.out.println(shallowPojo4);
System.out.println(shallowPojo5);
}
}
只能对基础属性以及字符串类型进行copy
深拷贝:
测试浅拷贝的方式 雷属性的hash一致即为浅copy
@Getter
@Setter
@AllArgsConstructor
@NoArgsConstructor
@ToString
public class ShallowCopyPojo implements Cloneable {
private String id;
private String name;
private ShallowPojo shallowPojo;
@Override
protected Object clone() throws CloneNotSupportedException {
return super.clone();
}
}
运行拷贝的类
public class DeepMain {
public static void main(String[] args) throws CloneNotSupportedException {
// 测试浅拷贝 存在对象属性的情况下 只是引用了地址 没有进行深拷贝
ShallowCopyPojo shallowCopyPojo = new ShallowCopyPojo("1", "张三", new ShallowPojo("2", "lisi"));
System.out.println("id: " + shallowCopyPojo.getId() + ", name: " + shallowCopyPojo.getName() + ",shallowPojo hash:" + shallowCopyPojo.getShallowPojo().hashCode());
ShallowCopyPojo shallowCopyPojo1 = (ShallowCopyPojo) shallowCopyPojo.clone();
System.out.println("id: " + shallowCopyPojo1.getId() + ", name: " + shallowCopyPojo1.getName() + ",shallowPojo hash:" + shallowCopyPojo1.getShallowPojo().hashCode());
}
}
深拷贝方式1 (不推荐使用)
@Getter
@Setter
@ToString
@NoArgsConstructor
@AllArgsConstructor
public class DeepCopyPojo1 implements Cloneable {
private String id;
private String name;
private DeepCopyPojoA deepCopyPojoA;
@Override
protected Object clone() throws CloneNotSupportedException {
DeepCopyPojo1 result = (DeepCopyPojo1)super.clone();
result.setDeepCopyPojoA((DeepCopyPojoA) result.getDeepCopyPojoA().clone());
return result;
}
}
@Getter
@Setter
@AllArgsConstructor
@NoArgsConstructor
class DeepCopyPojoA implements Cloneable {
private String id;
private String name;
@Override
protected Object clone() throws CloneNotSupportedException {
return super.clone();
}
}
运行拷贝的类
public class DeepMain {
public static void main(String[] args) throws CloneNotSupportedException {
// 深拷贝方式1
DeepCopyPojo1 deepCopyPojo1 = new DeepCopyPojo1("1", "张三", new DeepCopyPojoA("2", "李四"));
System.out.println("id: " + deepCopyPojo1.getId() + ", name: " + deepCopyPojo1.getName() + ",shallowPojo hash:" + deepCopyPojo1.getDeepCopyPojoA().hashCode());
DeepCopyPojo1 deepCopyPojoA = (DeepCopyPojo1) deepCopyPojo1.clone();
System.out.println("id: " + deepCopyPojoA.getId() + ", name: " + deepCopyPojoA.getName() + ",shallowPojo hash:" + deepCopyPojoA.getDeepCopyPojoA().hashCode());
}
}
深拷贝方式2(推荐使用)
@Getter
@Setter
@AllArgsConstructor
@NoArgsConstructor
public class DeepCopyPojo2 implements Cloneable, Serializable {
private String id;
private String name;
private DeepCopyPojoB deepCopyPojoB;
public DeepCopyPojo2 deepClone() {
ByteArrayOutputStream byteArrayOutputStream = null;
ObjectOutputStream objectOutputStream = null;
ByteArrayInputStream byteArrayInputStream = null;
ObjectInputStream objectInputStream = null;
try {
byteArrayOutputStream = new ByteArrayOutputStream();
objectOutputStream = new ObjectOutputStream(byteArrayOutputStream);
objectOutputStream.writeObject(this);
byteArrayInputStream = new ByteArrayInputStream(byteArrayOutputStream.toByteArray());
objectInputStream = new ObjectInputStream(byteArrayInputStream);
return (DeepCopyPojo2) objectInputStream.readObject();
} catch (IOException e) {
throw new RuntimeException(e);
} catch (ClassNotFoundException e) {
throw new RuntimeException(e);
} finally {
try {
if (Objects.nonNull(objectInputStream)) {
objectInputStream.close();
}
if (Objects.nonNull(byteArrayInputStream)) {
byteArrayInputStream.close();
}
if (Objects.nonNull(objectOutputStream)) {
objectOutputStream.close();
}
if (Objects.nonNull(byteArrayOutputStream)) {
byteArrayOutputStream.close();
}
} catch (Exception e) {
e.printStackTrace();
}
}
}
}
@Getter
@Setter
@AllArgsConstructor
@NoArgsConstructor
class DeepCopyPojoB implements Serializable {
private String id;
private String name;
}
运行拷贝的类
public class DeepMain {
public static void main(String[] args) throws CloneNotSupportedException {
// 测试浅拷贝 存在对象属性的情况下 只是引用了地址 没有进行深拷贝
ShallowCopyPojo shallowCopyPojo = new ShallowCopyPojo("1", "张三", new ShallowPojo("2", "lisi"));
System.out.println("id: " + shallowCopyPojo.getId() + ", name: " + shallowCopyPojo.getName() + ",shallowPojo hash:" + shallowCopyPojo.getShallowPojo().hashCode());
ShallowCopyPojo shallowCopyPojo1 = (ShallowCopyPojo) shallowCopyPojo.clone();
System.out.println("id: " + shallowCopyPojo1.getId() + ", name: " + shallowCopyPojo1.getName() + ",shallowPojo hash:" + shallowCopyPojo1.getShallowPojo().hashCode());
// 深拷贝方式1
DeepCopyPojo1 deepCopyPojo1 = new DeepCopyPojo1("1", "张三", new DeepCopyPojoA("2", "李四"));
System.out.println("id: " + deepCopyPojo1.getId() + ", name: " + deepCopyPojo1.getName() + ",shallowPojo hash:" + deepCopyPojo1.getDeepCopyPojoA().hashCode());
DeepCopyPojo1 deepCopyPojoA = (DeepCopyPojo1) deepCopyPojo1.clone();
System.out.println("id: " + deepCopyPojoA.getId() + ", name: " + deepCopyPojoA.getName() + ",shallowPojo hash:" + deepCopyPojoA.getDeepCopyPojoA().hashCode());
// 深拷贝方式2 推荐使用
DeepCopyPojo2 deepCopyPojo2 = new DeepCopyPojo2("1", "张三", new DeepCopyPojoB("2", "李四"));
System.out.println("id: " + deepCopyPojo2.getId() + ", name: " + deepCopyPojo2.getName() + ",shallowPojo hash:" + deepCopyPojo2.getDeepCopyPojoB().hashCode());
DeepCopyPojo2 deepCopyPojoB = deepCopyPojo2.deepClone();
System.out.println("id: " + deepCopyPojoB.getId() + ", name: " + deepCopyPojoB.getName() + ",shallowPojo hash:" + deepCopyPojoB.getDeepCopyPojoB().hashCode());
}
}

浙公网安备 33010602011771号