掌握Java设计模式之原型设计模式(4)

原创
2018/04/03 11:53
阅读数 686

概念

      原型设计模式其实并不是一种设计模式,当然换句话说并不是一种解决方案,它和简单工厂模式差不多,简单工厂做个if else判断就能当作一个设计模式来讲,那么原型设计模式也可以用implement cloneable来解决。

      这种做法是相当于newObject还是指向oldObject的地址,也就是说,二者实际上是一样的,未来也是一样的,随便对哪个对象进行更改,二者都会保持一致,因为可以把它们看做两个相同的“指针”;另外一种常见的做法是,重新创建一个对象,用new来实例化,这样就创建了另外一个对象,即向内存中再写入了一个对象,虽然内容一样,但地址不一样,但是这种做法费力,如果对象比较复杂的话。

      原型模式在这种需求下就诞生了,我们知道Object乃一切对象的父类(超类),并且Object有一个原生的clone方法,但是该方法的调用必须要求类实现了Cloneable接口,虽然Cloneable接口只是一个摆设,里面空空荡荡,姑且就当Cloneable接口是clone方法实现的一个标志吧!我们可以创建一个类实现Cloneable即可,在覆写clone方法即可完成该类的克隆了。

      浅复制,与深度复制的区别:浅复制克隆出来的对象改变可能会更改初始对象的值,深度复制克隆出来的对象与初始对象毫无关系

      浅复制代码:

public class Eye {

    private String name;

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

    public String getName() {
        return name;
    }

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

    @Override
    public String toString() {
        return "Eye{" +
                "name='" + name + '\'' +
                '}';
    }
}
import java.io.Serializable;

public class Person implements Cloneable,Serializable {

    private static final long serialVersionUID = -2050795770781171788L;

    private String name;

    private String address;

    Eye eye;

    public Person(){}

    public Person(Eye eye){
        this.eye = eye;
    }

    public String getName() {
        return name;
    }

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

    public String getAddress() {
        return address;
    }

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

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

    @Override
    public String toString() {
        return "Person{" +
                "name='" + name + '\'' +
                ", address='" + address + '\'' +
                ", eye=" + eye +
                '}';
    }
}
public class Main {


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

        Person person = new Person(new Eye("nameEyePerson"));

        person.setName("namePerson");

        person.setAddress("addressPerson");

        Person clonePerson = (Person) person.clone();

        clonePerson.setName("nameEye");

        clonePerson.setAddress("addressEye");

        clonePerson.eye.setName("cloneEye");

        System.out.println(person.toString());
        System.out.println(clonePerson.toString());

        System.out.println(person==clonePerson);
        System.out.println(person.equals(clonePerson));
        System.out.println(person.getClass().equals(clonePerson.getClass()));
        System.out.println(person.getClass()== clonePerson.getClass());

    }
}

结果:

Person{name='namePerson', address='addressPerson', eye=Eye{name='cloneEye'}}
Person{name='nameEye', address='addressEye', eye=Eye{name='cloneEye'}}
false
false
true
true

      深度复制:克隆出来的对象与原始对象没有关联

      在person类中添加deepclone方法

public Object deepClone() throws IOException, ClassNotFoundException {

    /* 写入当前对象的二进制流 */
    ByteArrayOutputStream bos = new ByteArrayOutputStream();
    ObjectOutputStream oos = new ObjectOutputStream(bos);
    oos.writeObject(this);

    /* 读出二进制流产生的新对象 */
    ByteArrayInputStream bis = new ByteArrayInputStream(bos.toByteArray());
    ObjectInputStream ois = new ObjectInputStream(bis);
    return ois.readObject();
}

      main中跟换函数

import java.io.IOException;

public class Main {


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

        Person person = new Person(new Eye("nameEyePerson"));

        person.setName("namePerson");

        person.setAddress("addressPerson");

        //Person clonePerson = (Person) person.clone();
        Person clonePerson = (Person) person.deepClone();

        clonePerson.setName("nameEye");

        clonePerson.setAddress("addressEye");

        clonePerson.eye.setName("cloneEye");

        System.out.println(person.toString());
        System.out.println(clonePerson.toString());

        System.out.println(person==clonePerson);
        System.out.println(person.equals(clonePerson));
        System.out.println(person.getClass().equals(clonePerson.getClass()));
        System.out.println(person.getClass()== clonePerson.getClass());

    }
}

结果:

Person{name='namePerson', address='addressPerson', eye=Eye{name='nameEyePerson'}}
Person{name='nameEye', address='addressEye', eye=Eye{name='cloneEye'}}
false
false
true
true

      这就是原型设计模式的例子,目前为止没有找到项目中用到的原型设计模式,这个博客也是看了几篇博客写的,没有应用场景,如果有,后续我会慢慢写上。

      这个克隆就是实现Object的方法,这也是一个公司的面试题,基类Object的所有方法你用过那些。

展开阅读全文
打赏
1
3 收藏
分享
加载中
更多评论
打赏
0 评论
3 收藏
1
分享
返回顶部
顶部