标签:car 浅拷贝 line san 复制 his nts 有一个 date
原型模式
原型模式(Prototype),用原型实例制定创建对象的种类,并且通过拷贝这些原型创建新的对象。[DP]
优点:
缺点:
Prototype:原型父类
ConcretePrototype1:子原型类
ConcretePrototype2:子原型类

例子:展示深拷贝和浅拷贝的区别,一个校牌类,一个学生类,校牌类持有一个学生类的对象,先创建一个三班 的张三校牌对象,然后拷贝一份,赋值为五班的李四,分别打印。
客户端调用类
/**
 * @ Author     :fonxi
 * @ Date       :2019/5/21 12:25
 * @ Description:客户端调用类
 */
public class TestController {
    public void print(){
        SchoolCard p1 = new SchoolCard("三班");
        p1.setStudent(new Student("张三"));
        SchoolCard c1 =  p1.Clone();
        c1.setId("五班");
        c1.getStudent().setName("李四");
        
        System.out.println("p1="+p1.getId()+" name="+p1.getStudent().getName());
        System.out.println("c1="+c1.getId()+" name="+c1.getStudent().getName());
    }
}
校牌类,注释的代码不用看,是深拷贝的代码
/**
 * @ Author     :fonxi
 * @ Date       :2019/5/21 12:27
 * @ Description:被拷贝的类,校牌类
 */
public class SchoolCard implements Cloneable{
    private String id;
    private Student student;
    public SchoolCard(String id){
        this.id = id;
    }
//    private SchoolCard(Student student){
//        this.student = student.Clone();
//    }
//
//    public SchoolCard Clone(){
//        SchoolCard concretePrototype1 = new SchoolCard(this.student);
//        concretePrototype1.setId(this.getId());
//        return concretePrototype1;
//    }
    public SchoolCard Clone(){
        try {
            return (SchoolCard) this.clone();
        } catch (CloneNotSupportedException e) {
            e.printStackTrace();
        }
        return null;
    }
    public void setStudent(Student student) {
        this.student = student;
    }
    public Student getStudent() { return student; }
    public void setId(String id) { this.id = id; }
    public String getId() { return id; }
}
学生类
/**
 * @ Author     :fonxi
 * @ Date       :2019/5/21 13:13
 * @ Description:被拷贝的类,学生类
 */
public class Student implements Cloneable{
//    public Student Clone(){
//        try {
//            return (Student) this.clone();
//        } catch (CloneNotSupportedException e) {
//            e.printStackTrace();
//        }
//        return null;
//    }
    public Student(String name){
        this.name = name;
    }
    private String name;
    public String getName() {
        return name;
    }
    public void setName(String name) {
        this.name = name;
    }
}
输出结果:
p1=三班 name=李四 c1=五班 name=李四
明明是一个张三一个李四,但是都是李四,这里就是因为引用类型需要深拷贝,否则会覆盖前面的对象。
校牌类修改
/**
 * @ Author     :fonxi
 * @ Date       :2019/5/21 12:27
 * @ Description:被拷贝的类,校牌类
 */
public class SchoolCard implements Cloneable{
    private String id;
    private Student student;
    public SchoolCard(String id){
        this.id = id;
    }
    private SchoolCard(Student student){
        this.student = student.Clone();
    }
    public SchoolCard Clone(){
        SchoolCard concretePrototype1 = new SchoolCard(this.student);
        concretePrototype1.setId(this.getId());
        return concretePrototype1;
    }
//    public SchoolCard Clone(){
//        try {
//            return (SchoolCard) this.clone();
//        } catch (CloneNotSupportedException e) {
//            e.printStackTrace();
//        }
//        return null;
//    }
    public void setStudent(Student student) { this.student = student; }
    public Student getStudent() { return student; }
    public void setId(String id) { this.id = id; }
    public String getId() { return id; }
}
学生类修改
public class Student implements Cloneable{
    public Student Clone(){
        try {
            return (Student) this.clone();
        } catch (CloneNotSupportedException e) {
            e.printStackTrace();
        }
        return null;
    }
    public Student(String name){
        this.name = name;
    }
    private String name;
    public String getName() {
        return name;
    }
    public void setName(String name) {
        this.name = name;
    }
}
输出
p1=三班 name=张三 c1=五班 name=李四
perfect
原型模式虽然可以带节省资源,方便对象的初始化,但是浅拷贝会有覆盖的问题,深拷贝需要一层一层的深入的修改,很复杂。需要根据场景慎重使用
标签:car 浅拷贝 line san 复制 his nts 有一个 date
原文地址:https://www.cnblogs.com/fonxi/p/10909228.html