# 闲聊

最近看到原型模式,老师最先开始举了一个例子,假如每个对象的内容都是一样的,这样的对象需要十个,你要怎么去创建这十个对象?我首先想到的就是我要去new十个,但这绝不是最好的方法。记得以前通过java四大接口之一Cloneableclone方法创建过对象,原型模式就是用这种方法实现的。

我有一个疑问,当创建一个对象足够简单,原型模式存在的意义是什么?可能写完这个我就明白了。学原型模式必不可少接触深克隆和浅克隆,有区别是因为类的成员变量中包含引用数据(即对象),浅克隆引用数据类型的地址不会改变,深克隆引用数据类型的地址会重新分配。

克隆的两个对象地址是一样的吗?

# 什么是原型模式

原型模式是一种创建型设计模式,Prototype模式允许一个对象再创建另外一个可定制的对象,根本无需知道任何如何创建的细节,工作原理是:通过将一个原型对象传给那个要发动创建的对象,这个要发动创建的对象通过请求原型对象拷贝它们自己来实施创建。

# 原型模式能解决什么问题

某些结构复杂的对象的创建工作(这个是确实,假如创建一个对象很复杂,但是对象的内容是一致的,通过原型模式确实很方便);由于需求的变化,对象经常面临着剧烈的变化,但是它们却拥有比较稳定的接口(这个概念搞不清楚)。

我觉得能用到的时候,也就是当创建这个对象比较复杂的时候。

# 浅克隆与深克隆

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

深克隆:创建一个新对象,属性中引用的其他对象也会被克隆,不在指向原有对象地址。

# 原型模式的UML图

<<Interface>>
Prototype



+ clone(): Prototype

<<Interface>>...
ConcretePrototype2+ clone(): PrototypeConcretePrototype1+ clone(): PrototypeClient+ prototype: Prototype+ Client()+ operation(): void
Viewer does not support full SVG 1.1

一共有三个角色,客户角色,抽象原型角色,具体原型角色,居于此就可以构建一个很好的原型模式。

# 浅克隆

接下来用代码实现一下浅克隆与深克隆。

package org.example.sheep;
public class ShallowClone {
    public static void main(String[] args) throws CloneNotSupportedException {
        Person person1 = new Person("小黑",20);
        person1.head = new Head();
        Person person2 = (Person) person1.clone();
        System.out.println(person1);
        System.out.println(person2);
        System.out.println(person1.head == person2.head);
    }
}
class Person implements Cloneable{
    String name;
    Integer age;
    Head head;
    public Person(String name, Integer age) {
        this.name = name;
        this.age = age;
    }
    @Override
    protected Object clone() throws CloneNotSupportedException {
        return super.clone();
    }
}
class Head implements Cloneable{
    @Override
    protected Object clone() throws CloneNotSupportedException {
        return super.clone();
    }
}

输出结果为:

org.example.sheep.Person@677327b6
org.example.sheep.Person@14ae5a5
true

true代表引用数据相同,这个就是浅克隆。

# 深克隆

package org.example.sheep;
public class DeepClone {
    public static void main(String[] args) throws CloneNotSupportedException {
        Person person1 = new Person("小黑",20);
        person1.head = new Head();
        Person person2 = (Person) person1.clone();
        System.out.println(person1);
        System.out.println(person2);
        System.out.println(person1.head == person2.head);
    }
}
class Person implements Cloneable{
    String name;
    Integer age;
    Head head;
    public Person(String name, Integer age) {
        this.name = name;
        this.age = age;
    }
    @Override
    protected Object clone() throws CloneNotSupportedException {
        Person person = (Person) super.clone();
        person.head = (Head) head.clone();
        return person;
    }
}
class Head implements Cloneable{
    @Override
    protected Object clone() throws CloneNotSupportedException {
        return super.clone();
    }
}

输出结果为:

org.example.sheep.Person@677327b6
org.example.sheep.Person@14ae5a5
false

false代表引用数据不相同,这个就是深克隆。