0
点赞
收藏
分享

微信扫一扫

2024微信小程序期末大作业-点奶茶微信小程序(后端nodejs-server)(附下载链接)_微信小程序期末大作业百度网盘下载

灯火南山 2024-07-24 阅读 11

设计模式——原型模式

传统模式创建大量对象

代码实现

public class Citation {
    private String name;

    @Override
    public String toString() {
        return "Citation{" +
                "name='" + name + '\'' +
                '}';
    }
}

创建5个对象

public class Client {
    public static void main(String[] args) {
        Citation citation = new Citation();
        Citation citation1 = new Citation();
        Citation citation2 = new Citation();
        Citation citation3 = new Citation();
        Citation citation4 = new Citation();
    }
}

传统方式的优缺点

解决思路

原型模式

1.1 基本介绍

一句话解释就是:用一个已经创建的实例作为原型,通过复制该原型对象来创建一个和原型对象相同的新对象。

1.2 原型模式创建

Java中的Object类中提供了 clone() 方法来实现浅克隆。 Cloneable 接口是上面的类图中的抽
象原型类,而实现了Cloneable接口的子实现类就是具体的原型类。代码如下:

public class Citation implements Cloneable{
    private String name;

    public Citation(String name) {
        this.name = name;
        System.out.println(name);
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    @Override
    public String toString() {
        return "Citation{" +
                "name='" + name + '\'' +
                '}';
    }

    @Override
    protected Citation clone() throws CloneNotSupportedException {
        return (Citation) super.clone();
    }
}
public class Client {
    public static void main(String[] args) throws CloneNotSupportedException {
        Citation citation = new Citation("三好学生");
        Citation clone = citation.clone();
    }
}

1.3 深拷贝和浅拷贝

1.3.1 浅拷贝

浅克隆:创建一个新对象,新对象的属性和原来对象完全相同,对于非基本类型属性,仍指向原
有属性所指向的对象的内存地址。

代码示例:

public class Citation implements Cloneable{
    private String name;

    private Student student;

    public Student getStudent() {
        return student;
    }

    public void setStudent(Student student) {
        this.student = student;
    }

    public Citation() {
    }

    public Citation(String name) {
        this.name = name;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public void show() {
        System.out.println(name + "同学:在2020学年第一学期中表现优秀,被评为三好学生。特发此状!");
    }

    @Override
    public String toString() {
        return "Citation{" +
                "name='" + name + '\'' +
                '}';
    }

    @Override
    protected Object clone() throws CloneNotSupportedException {
        return super.clone();
    }
}
public class Student {
    private String address;
    private String name;

    @Override
    public String toString() {
        return "Student{" +
                "address='" + address + '\'' +
                ", name='" + name + '\'' +
                '}';
    }

    public String getAddress() {
        return address;
    }

    public void setAddress(String address) {
        this.address = address;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }
}

public class Client {
    public static void main(String[] args) throws CloneNotSupportedException {
        Citation citation = new Citation();
        citation.setName("三好学生");
        Student student = new Student();
        student.setName("张三");
        citation.setStudent(student);
        Citation clone = (Citation) citation.clone();
        clone.setName("五好学生");
        Student student1 = clone.getStudent();
        student1.setName("李四");
        citation.show();
        clone.show();
        System.out.println(student == student1);
        System.out.println(citation.getStudent());
        System.out.println(clone.getStudent());
    }
}

最后输出的结果

三好学生同学:在2020学年第一学期中表现优秀,被评为三好学生。特发此状!
五好学生同学:在2020学年第一学期中表现优秀,被评为三好学生。特发此状!
true
Student{address='null', name='李四'}
Student{address='null', name='李四'}

说明
stu对象和stu1对象是同一个对象,就会产生将stu1对象中name属性值改为“李四”,两个
Citation(奖状)对象中显示的都是李四。这就是浅克隆的效果,对具体原型类(Citation)中的
引用类型的属性进行引用的复制。

1.3.1 深拷贝

代码示例:

重写 clone 方法来实现深拷贝

student类实现clone方法,citation类型重写clone方法实现,对引用类型的数据进行处理:

public class Citation implements Cloneable{
    private String name;

    private Student student;

    public Student getStudent() {
        return student;
    }

    public void setStudent(Student student) {
        this.student = student;
    }

    public Citation() {
    }

    public Citation(String name) {
        this.name = name;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public void show() {
        System.out.println(name + "同学:在2020学年第一学期中表现优秀,被评为三好学生。特发此状!");
    }

    @Override
    public String toString() {
        return "Citation{" +
                "name='" + name + '\'' +
                '}';
    }

    @Override
    protected Object clone() throws CloneNotSupportedException {
        Citation citation = (Citation) super.clone();
        // 对引用类型 进行clone方法处理
        citation.student = (Student) citation.getStudent().clone();
        return citation;
    }
}

得到的结果是:

三好学生同学:在2020学年第一学期中表现优秀,被评为三好学生。特发此状!
五好学生同学:在2020学年第一学期中表现优秀,被评为三好学生。特发此状!
false
Student{address='null', name='张三'}
Student{address='null', name='李四'}
通过对象序列化实现深拷贝:

类记得实现Serializable接口,不然会报错的,并且属性里面有对象属性也需要实现。

public class Citation implements Cloneable, Serializable {
    private String name;

    private Student student;

    public Student getStudent() {
        return student;
    }

    public void setStudent(Student student) {
        this.student = student;
    }

    public Citation() {
    }

    public Citation(String name) {
        this.name = name;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public void show() {
        System.out.println(name + "同学:在2020学年第一学期中表现优秀,被评为三好学生。特发此状!");
    }

    @Override
    public String toString() {
        return "Citation{" +
                "name='" + name + '\'' +
                '}';
    }

    public Object deepClone(){
        ByteArrayInputStream bis = null;
        ByteArrayOutputStream bos = null;
        ObjectInputStream ois = null;
        ObjectOutputStream oos = null;
        try{
            // 序列化
            bos = new ByteArrayOutputStream();
            oos = new ObjectOutputStream(bos);
            oos.writeObject(this);

            // 反序列化
            bis = new ByteArrayInputStream(bos.toByteArray());
            ois = new ObjectInputStream(bis);
            return  ois.readObject();

        }catch (Exception e){
            e.printStackTrace();
            return null;
        }
    }

    @Override
    protected Object clone() throws CloneNotSupportedException {
        Citation citation = (Citation) super.clone();
        // 对引用类型 进行clone方法处理
//        citation.student = (Student) citation.getStudent().clone();
        return citation;
    }
}

public class Student implements Cloneable, Serializable {
    private String address;
    private String name;

    @Override
    public String toString() {
        return "Student{" +
                "address='" + address + '\'' +
                ", name='" + name + '\'' +
                '}';
    }

    public String getAddress() {
        return address;
    }

    public void setAddress(String address) {
        this.address = address;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

//    @Override
//    protected Object clone() throws CloneNotSupportedException {
//        return super.clone();
//    }
}

注意,这里调用的是deepClone方法

public class Client {
    public static void main(String[] args) throws CloneNotSupportedException {
        Citation citation = new Citation();
        citation.setName("三好学生");
        Student student = new Student();
        student.setName("张三");
        citation.setStudent(student);
        Citation clone = (Citation) citation.deepClone();
        clone.setName("五好学生");
        Student student1 = clone.getStudent();
        student1.setName("李四");
        citation.show();
        clone.show();
        System.out.println(student == student1);
        System.out.println(citation.getStudent());
        System.out.println(clone.getStudent());
    }
}

结果输出:

三好学生同学:在2020学年第一学期中表现优秀,被评为三好学生。特发此状!
五好学生同学:在2020学年第一学期中表现优秀,被评为三好学生。特发此状!
false
Student{address='null', name='张三'}
Student{address='null', name='李四'}

序列化拷贝的核心代码:
public Object deepClone(){
        ByteArrayInputStream bis = null;
        ByteArrayOutputStream bos = null;
        ObjectInputStream ois = null;
        ObjectOutputStream oos = null;
        try{
            // 序列化
            bos = new ByteArrayOutputStream();
            oos = new ObjectOutputStream(bos);
            oos.writeObject(this);

            // 反序列化
            bis = new ByteArrayInputStream(bos.toByteArray());
            ois = new ObjectInputStream(bis);
            return  ois.readObject();

        }catch (Exception e){
            e.printStackTrace();
            return null;
        }
    }

总结

举报

相关推荐

0 条评论