设计模式三(原型模式)

发布时间:2024年01月24日

在开发过程中,创建多个数据相同的对象,每次new都开销比较大,在这里可以使用对象克隆,以先创建的原型对象为模板进行对象的复制。这种模式是实现了一个原型接口,该接口用于创建当前对象的克隆。当直接创建对象的代价比较大时,则采用这种模式。例如,一个对象需要在一个高代价的数据库操作之后被创建。我们可以缓存该对象,在下一个请求时返回它的克隆,在需要的时候更新数据库,以此来减少数据库调用

浅克隆

在浅克隆中,如果原型对象的成员变量是值类型,将复制一份给克隆对象;如果原型对象的成员变量是引用类型,则将引用对象的地址复制一份给克隆对象,也就是说原型对象和克隆对象的成员变量指向相同的内存地址

?
public class Person implements ?Cloneable{
??
? ? ? int num;
? ? ? String name;
??
? ? ?public Person() {
? ?  }
??
? ? ?public Person(int num, String name) {
? ? ? ? ?this.num = num;
? ? ? ? ?this.name = name;
? ?  }
??
? ? ?public int getNum() {
? ? ? ? ?return num;
? ?  }
??
? ? ?public void setNum(int num) {
? ? ? ? ?this.num = num;
? ?  }
??
? ? ?public String getName() {
? ? ? ? ?return name;
? ?  }
??
? ? ?public void setName(String name) {
? ? ? ? ?this.name = name;
? ?  }
??
??
??
? ? ?@Override
? ? ?protected Person clone() throws CloneNotSupportedException {
? ? ? ? ?Person person = (Person)super.clone();
? ? ? ? ?return person;
? ?  }
??
? ? ?@Override
? ? ?public String toString() {
? ? ? ? ?return "Person{" +
? ? ? ? ? ? ? ? ?"num=" + num +
? ? ? ? ? ? ? ? ?", name='" + name + '\'' +
? ? ? ? ? ? ? ? ?'}';
? ?  }
?}
?public class Test {
??
? ? ?public static void main(String[] args) throws CloneNotSupportedException {
??
? ? ? ? ?Person p1 = new Person(100,"jim");
? ? ? ? ?Person p2 =p1.clone();//clone方法 返回一个新对象
? ? ? ? ?p2.name = "tom";
? ? ? ? ?System.out.println(p1);//100 ,jim
? ? ? ? ?System.out.println(p2);//100 tom
??
? ? ? ? ?System.out.println(p1==p2);//false
??
? ?  }
?}

深克隆

多层克隆

在深克隆中,无论原型对象的成员变量是值类型还是引用类型,都将复制一份给克隆对象,深克隆将原型对象的所有引用对象也复制一份给克隆对象。简单来说,在深克隆中,除了对象本身被复制外,对象所包含的所有成员变量也将复制

?public class Person implements ?Cloneable{
??
? ? ? int num;
? ? ? String name;
? ? ? Address address;
??
? ? ?public Person() {
??
? ?  }
??
? ? ?public Person(int num, String name) {
? ? ? ? ?this.num = num;
? ? ? ? ?this.name = name;
? ?  }
??
? ? ?public int getNum() {
? ? ? ? ?return num;
? ?  }
??
? ? ?public void setNum(int num) {
? ? ? ? ?this.num = num;
? ?  }
??
? ? ?public String getName() {
? ? ? ? ?return name;
? ?  }
??
? ? ?public void setName(String name) {
? ? ? ? ?this.name = name;
? ?  }
??
? ? ?public Address getAddress() {
? ? ? ? ?return address;
? ?  }
??
? ? ?public void setAddress(Address address) {
? ? ? ? ?this.address = address;
? ?  }
??
? ? ?@Override
? ? ?protected Person clone() throws CloneNotSupportedException {
? ? ? ? ?Person person = (Person)super.clone();
? ? ? ? ?person.address = address.clone(); ? //深度复制  联同person中关联的对象也一同克隆.
? ? ? ? ?return person;
? ?  }
??
? ? ?@Override
? ? ?public String toString() {
? ? ? ? ?return "Person{" +
? ? ? ? ? ? ? ? ?"num=" + num +
? ? ? ? ? ? ? ? ?", name='" + name + '\'' +
? ? ? ? ? ? ? ? ?", address=" + address +
? ? ? ? ? ? ? ? ?'}';
? ?  }
?}
??
?public class Address ?implements Cloneable{
??
? ? ? String ?address;
??
? ? ?public String getAddress() {
? ? ? ? ?return address;
? ?  }
??
? ? ?public void setAddress(String address) {
? ? ? ? ?this.address = address;
? ?  }
??
? ? ?@Override
? ? ?public String toString() {
? ? ? ? ?return "Address{" +
? ? ? ? ? ? ? ? ?"address='" + address + '\'' +
? ? ? ? ? ? ? ? ?'}';
? ?  }
??
? ? ? @Override
? ? ?protected Address clone() throws CloneNotSupportedException {
? ? ? ? ?return (Address) super.clone();
? ?  }
?}

序列化

?
public class Address ?implements Serializable {
??
? ? ? String ?address;
??
? ? ?public String getAddress() {
? ? ? ? ?return address;
? ?  }
??
? ? ?public void setAddress(String address) {
? ? ? ? ?this.address = address;
? ?  }
??
? ? ?@Override
? ? ?public String toString() {
? ? ? ? ?return "Address{" +
? ? ? ? ? ? ? ? ?"address='" + address + '\'' +
? ? ? ? ? ? ? ? ?'}';
? ?  }
??
?}
?
public class Person implements Serializable {
??
? ? ? int num;
? ? ? String name;
? ? ? Address address;
??
? ? ?public Person() {
? ?  }
??
? ? ?public Person(int num, String name) {
? ? ? ? ?this.num = num;
? ? ? ? ?this.name = name;
? ?  }
??
? ? ?public int getNum() {
? ? ? ? ?return num;
? ?  }
??
? ? ?public void setNum(int num) {
? ? ? ? ?this.num = num;
? ?  }
??
? ? ?public String getName() {
? ? ? ? ?return name;
? ?  }
??
? ? ?public void setName(String name) {
? ? ? ? ?this.name = name;
? ?  }
??
? ? ?public Address getAddress() {
? ? ? ? ?return address;
? ?  }
??
? ? ?public void setAddress(Address address) {
? ? ? ? ?this.address = address;
? ?  }
??
? ? ?/**
? ? ? * 自定义克隆方法
? ? ? * @return
? ? ? */
? ? ?public Person myclone() {
? ? ? ? ? ? ?Person person = null;
? ? ? ? ? ? ? ?try { // 将该对象序列化成流,因为写在流里的是对象的一个拷贝,而原对象仍然存在于JVM里面。所以利用这个特性可以实现对象的深拷贝
? ? ? ? ? ? ? ? ? ? ? ByteArrayOutputStream baos = new ByteArrayOutputStream();
? ? ? ? ? ? ? ? ? ? ? ?ObjectOutputStream oos = new ObjectOutputStream(baos);
? ? ? ? ? ? ? ? ? ? ? ?oos.writeObject(this);
? ? ? ? ? ? ?// 将流序列化成对象
? ? ? ? ? ? ? ? ? ? ?ByteArrayInputStream bais = new ByteArrayInputStream(baos.toByteArray());
? ? ? ? ? ? ? ? ? ? ? ObjectInputStream ois = new ObjectInputStream(bais);
? ? ? ? ? ? ? ? ? ? ? person = (Person) ois.readObject();
? ? ? ? ? ? ? ? ?  } catch (IOException e) {
? ? ? ? ? ? ? ? ? ? ? e.printStackTrace();
? ? ? ? ? ? ? ? ?  } catch (ClassNotFoundException e) {
? ? ? ? ? ? ? ? ? ? ? e.printStackTrace();
? ? ? ? ? ? ? ? ? }
? ? ? ? ? ? ? return person;
? ? ? ? ?  }
??
??
? ? ?@Override
? ? ?public String toString() {
? ? ? ? ?return "Person{" +
? ? ? ? ? ? ? ? ?"num=" + num +
? ? ? ? ? ? ? ? ?", name='" + name + '\'' +
? ? ? ? ? ? ? ? ?", address=" + address +
? ? ? ? ? ? ? ? ?'}';
? ?  }
?}

?练习

题目页面 (kamacoder.com)

import java.util.Scanner;

public class Main {

    public static void main(String[] args) throws CloneNotSupportedException {
        Scanner scanner = new Scanner(System.in);
        int num = scanner.nextInt();
        while(num-->0){
            String color = scanner.next();
            int width = scanner.nextInt();
            int height = scanner.nextInt();
            Prototype prototype = new Prototype(color, width, height);
            Prototype clone = prototype.clone();
            System.out.println(clone.toString());
        }
    }
}

class Prototype implements Cloneable{
    private String color;
    private int width;
    private int height;

    public Prototype(String color, int width, int height) {
        this.color = color;
        this.width = width;
        this.height = height;
    }

    @Override
    public String toString() {
        return "Color: " + color + ", Width: " + width + ", Height: " + height;
    }

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


}

文章来源:https://blog.csdn.net/weixin_64704029/article/details/135829459
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。