大学的时候毕业论文太难写了,所以直接抄同学的,但是这种你并不是一个字一个字的重写。而是使用cv大法(ctrl+c和ctrl+v),直接将毕业论文进行复制粘贴。然后自己就可以安心的去打游戏了。
二 实现原理原型模式是一种创建型模式,例如我们要创建一个Student对象都是采用的new Student();但是有些时候对象的创建十分复杂,这个时候原型模式就登场了,就像毕业论文太长了自己写太麻烦。所以我们选择复制。
通过将一个原型对象传给那个要发动创建的对象,这个要发动创建的对象通过请求原型对象拷贝它们自己来实施创建,即 对象.clone()
- Prototype : 原型类,声明一个克隆自己的接口
- ConcretePrototype: 具体的原型类, 实现一个克隆自己的 *** 作
- Client: 让一个原型对象克隆自己,从而创建一个新的对象(属性一样)
申明原型类型 实现Cloneable接口
@Getter
@Setter
public class Student implements Cloneable {
private String name;
private String age;
private Teacher teacher;
@Override
protected Student clone() throws CloneNotSupportedException {
Student clone = (Student) super.clone();
return clone;
}
}
@Setter
@Getter
public class Teacher implements Cloneable{
private String teacherName;
@Override
protected Teacher clone() throws CloneNotSupportedException {
Teacher clone = (Teacher)super.clone();
return clone;
}
}
客户端调用原型拷贝
public class Client {
@SneakyThrows
public static void main(String[] args) {
Student student = new Student();
student.setAge("18");
student.setName("小明");
Teacher teacher = new Teacher();
student.setTeacher(teacher);
Student clone = student.clone();
System.out.println(student);
System.out.println(clone);
System.out.println(clone.getTeacher());
System.out.println(student.getTeacher());
}
}
运行结果
com.cncloud.prototype.Student@19e1023e
com.cncloud.prototype.Student@7cef4e59
com.cncloud.prototype.Teacher@64b8f8f4
com.cncloud.prototype.Teacher@64b8f8f4
从上面的运行结果可以看出通过clone创建的对象是一个新对象(引用地址不一样),通过浅拷贝实现对新对象的属性值进行复制的
四 深拷贝和浅拷贝浅拷贝
对于数据类型是基本数据类型的成员变量,浅拷贝会直接进行值传递,也就是将该属性值复制一份给新的对象
对于数据类型是引用数据类型的成员变量,比如说成员变量是某个数组、某个类的对象等,那么浅拷贝会进行引用传递,也就是只是将该成员变量的引用值(内存地址)复制一份给新的对象。因为实际上两个对象的该成员变量都指向同一个实例。在这种情况下,在一个对象中修改该成员变量会影响到另一个对象的该成员变量值
深拷贝
复制对象的所有基本数据类型的成员变量值
为所有引用数据类型的成员变量申请存储空间,并复制每个引用数据类型成员变量所引用的对象,直到该对象可达的所有对象。也就是说,对象进行深拷贝要对整个对象进行拷贝
4.1 重写clone方法来实现深拷贝@Getter
@Setter
public class Student implements Cloneable {
private String name;
private String age;
private Teacher teacher;
@Override
protected Student clone() throws CloneNotSupportedException {
Student clone = (Student) super.clone();
Teacher teacher = clone.getTeacher().clone();//调用clone方法重新复制
clone.setTeacher(teacher);
return clone;
}
}
@Setter
@Getter
public class Teacher implements Cloneable{
private String teacherName;
@Override
protected Teacher clone() throws CloneNotSupportedException {
Teacher clone = (Teacher)super.clone();
return clone;
}
}
public class Client {
@SneakyThrows
public static void main(String[] args) {
Student student = new Student();
student.setAge("18");
student.setName("小明");
Teacher teacher = new Teacher();
student.setTeacher(teacher);
Student clone = student.clone();
System.out.println(student);
System.out.println(clone);
System.out.println(clone.getTeacher());
System.out.println(student.getTeacher());
}
}
运行结果:
com.cncloud.prototype.Student@19e1023e
com.cncloud.prototype.Student@7cef4e59
com.cncloud.prototype.Teacher@64b8f8f4
com.cncloud.prototype.Teacher@2db0f6b2
这种实现方式过于复杂,一般不使用
4.2 通过对象序列化实现深拷贝@Getter
@Setter
public class Student implements Cloneable, Serializable {
private String name;
private String age;
private Teacher teacher;
@Override
protected Student clone() throws CloneNotSupportedException {
Student clone = (Student) super.clone();
Teacher teacher = clone.getTeacher().clone();
clone.setTeacher(teacher);
return clone;
}
public Student serializableClone() {
//创建流对象
ByteArrayOutputStream bos = null;
ObjectOutputStream oos = null;
ByteArrayInputStream bis = null;
ObjectInputStream ois = null;
try {
//序列化
bos = new ByteArrayOutputStream();
oos = new ObjectOutputStream(bos);
oos.writeObject(this); //当前这个对象以对象流的方式输出
//反序列化
bis = new ByteArrayInputStream(bos.toByteArray());
ois = new ObjectInputStream(bis);
Student copyObj = (Student)ois.readObject();
return copyObj;
} catch (Exception e) {
e.printStackTrace();
return null;
} finally {
//关闭流
try {
bos.close();
oos.close();
bis.close();
ois.close();
} catch (Exception e2) {
// TODO: handle exception
System.out.println(e2.getMessage());
}
}
}
}
public class Client {
@SneakyThrows
public static void main(String[] args) {
Student student = new Student();
student.setAge("18");
student.setName("小明");
Teacher teacher = new Teacher();
student.setTeacher(teacher);
Student serializableClone = student.serializableClone();
System.out.println(student.getTeacher());
System.out.println(serializableClone.getTeacher());
}
}
运行结果:
com.cncloud.prototype.Teacher@3ecf72fd
com.cncloud.prototype.Teacher@5315b42e
五 总结
原型模式一般是解决对象的创建比较复杂的场景,原型模式优缺点如下
优点:能够解决复杂对象的创建,同时进行解耦,如果复杂的每次自己创建,再具体产品进行修改后,业务代码全部可能会进行调整。
缺点:每个具体的产品必须要实现Cloneable接口,同时如果要实现深拷贝实际上是比较复杂的。
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)