Java 原型模式

发布时间 2023-12-28 15:48:59作者: yan061

原型模式是一种创建型设计模式,用于在保证性能的情况下创建新的对象实例。原型模式允许一个对象再创建另外一个可定制的对象,而无需知道创建的细节。其工作原理是通过拷贝实现对象创建,即clone()。
但是我们通过new也能创建一个属性一样的对象,两者的区别是什么呢?

  • new操作符:用于创建一个新的对象实例。该操作会调用构造函数以初始化对象并分配所需的内存空间,返回指向该对象的引用。new操作符需要调用构造函数来初始化对象,并且会分配独立的内存空间来存储新对象。
  • 克隆方法:克隆方法是Object类中定义的一种浅拷贝操作方法。该方法使用当前对象的副本来创建一个新的对象,而无需调用任何构造函数,并将其返回给调用者。与new不同的是,clone创建的是原始对象的复制品。这个过程需要对象实现 Cloneable 接口(否则会抛出 CloneNotSupportedException 异常)和覆盖 clone() 方法,以便在运行时复制对象的所有字段。克隆方法可以在已有对象的内存地址上创建新对象,避免构造器的执行,并且可以快速地复制对象的所有属性值。
    总结来说,通过“new”操作符创建新对象需要调用构造函数并分配独立的内存空间,而克隆对象则是在已有对象的内存地址上创建新对象,避免构造器的执行,并且可以快速地复制对象的所有属性值。

下面是Clone的例子(浅拷贝,基础数据类型是值传递,其他对象则是引用传递)

Friend类

public class Friend {
    String name;

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

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

?的类

public class Sheep implements Cloneable{

    String name;
    int age;
    String colour;
    Friend friend;

    public Sheep(String name, int age, String colour,Friend friend) {
        this.name = name;
        this.age = age;
        this.colour = colour;
        this.friend = friend;
    }

    @Override
    public String toString() {
        return "Sheep{" +
                "name='" + name + '\'' +
                ", age=" + age +
                ", colour='" + colour + '\'' +
                ", friend=" + friend +
                '}';
    }

    @Override
    protected Sheep clone() throws CloneNotSupportedException {

        return (Sheep) super.clone();
    }
}

客户端去创建并克隆羊

public class CloneSheep {

    public static void main(String[] args) throws CloneNotSupportedException {

        Sheep sheep = new Sheep("tom", 1, "black", new Friend("jerry"));
        System.out.println(sheep);

        Sheep sheep1 = sheep.clone();
        Sheep sheep2 = sheep.clone();
        Sheep sheep3 = sheep.clone();
        System.out.println("sheep1 "+sheep1+" friend" +sheep1.friend.hashCode());
        System.out.println("sheep2 "+sheep2+" friend" +sheep2.friend.hashCode());
        System.out.println("sheep3 "+sheep3+" friend" +sheep3.friend.hashCode());
    }
}

输出结果为

Sheep{name='tom', age=1, colour='black', friend=Friend{name='jerry'}}
sheep1 Sheep{name='tom', age=1, colour='black', friend=Friend{name='jerry'}} friend1494279232
sheep2 Sheep{name='tom', age=1, colour='black', friend=Friend{name='jerry'}} friend1494279232
sheep3 Sheep{name='tom', age=1, colour='black', friend=Friend{name='jerry'}} friend1494279232

那如果我想实现深拷贝的效果呢?