原型模式

167 阅读2分钟

定义

使用原型实例指定创建对象的种类,并且通过拷贝这些原型创建新的对象。

注意点

通过该模式创建的对象是全新的对象,在内部中拥有新的地址。

角色

Prototype(抽象原型类)

声明克隆方法的接口,是所有具体原型类的公共父类。

ConcretePrototype(具体原型类)

抽象原型类中方法的具体实现。

Client(客户类)

让一个原型对象克隆自身从而创建一个新的对象。

实现方法(Java)

浅拷贝

通过实现Cloneable接口快速实现。

public class Student implements Cloneable {
    private String name;
    private int age;

    public String getName() {
        return name;
    }

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

    public int getAge() {
        return age;
    }

    public void setAge(int age) {
        this.age = age;
    }

    public Student(String name, int age) {
        this.name = name;
        this.age = age;
    }

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

    @Override
    public Student clone() {
        Object object = null;
        try {
            object = super.clone();
            return (Student) object;
        } catch (CloneNotSupportedException e) {
            System.out.println("不支持复制");
            return null;
        }
    }

    public static void main(String[] args) {
        Student xiaohong = new Student("小红", 12);
        Student copy = xiaohong.clone();
        copy.setName("copy");
        copy.setAge(18);
        System.out.println(xiaohong.toString());
        System.out.println(copy.toString());
    }
}

测试结果:

Student{name='小红', age=12}
Student{name='copy', age=18}

深拷贝

要点:均实现Serializable接口。 父亲类:

public class Father implements Serializable {
    private String name;
    private int age;

    public String getName() {
        return name;
    }

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

    public int getAge() {
        return age;
    }

    public void setAge(int age) {
        this.age = age;
    }

    public Father(String name, int age) {
        this.name = name;
        this.age = age;
    }
}

家庭类:

public class Family implements Serializable {
    private Father father;

    public Father getFather() {
        return father;
    }

    public void setFather(Father father) {
        this.father = father;
    }

    public Family deepClone() throws IOException, ClassNotFoundException {
        //  将对象写入流中
        ByteArrayOutputStream bao = new ByteArrayOutputStream();
        ObjectOutputStream oss = new ObjectOutputStream(bao);
        oss.writeObject(this);

        //  将对象从流中取出
        ByteArrayInputStream bis = new ByteArrayInputStream(bao.toByteArray());
        ObjectInputStream ois = new ObjectInputStream(bis);
        return (Family) ois.readObject();

    }

    public static void main(String[] args) {
        Father father =new Father("小头爸爸",20);
        Family family1 =new Family();
        family1.setFather(father);
        Family family2 = null;
        try {
            family2 = family1.deepClone();
        }catch (Exception e){
            System.out.println("深拷贝失败");
        }
        System.out.println(family1 == family2);
        System.out.println(family1.getFather() == family2.getFather());
    }
}

测试结果:

false
false

适用场景

(1)批量创建相似的复杂对象。

(2)系统需要保存对象的状态,且对象的状态变化很小,亦或是对象本身占用的内存很小。

(3)需要避免分层次的工厂类来创建分层次的对象,且类的实例对象只有一个或很少的几个组合状态。