设计模式 原型模式

Posted custoyth

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了设计模式 原型模式相关的知识,希望对你有一定的参考价值。

1.设计模式背景

在某些场景下,我们需要拷贝对象,普通设计方式会直接new一个新的对象,然后setter各种属性。缺点是:这种方式太麻烦。
这时候就可以使用到原型模式,通过Object的clone方法克隆对象,或者通过流。

2.使用方法

Object对象的clone方法,能够浅拷贝对象的primitive field,使用方式如下:

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

    public String getName() {
        return name;
    }

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

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

    @Override
    public String toString() {
        return "Person{" +
                "name=‘" + name + ‘‘‘ +
                ", age=" + age +
                ‘}‘;
    }


}

3.如果存在引用型成员变量怎么办?

public class Person implements  Cloneable{
    private String name;
    private int age;
    private Department department;

经过测试发现,克隆对象中的department是同一个对象。

Person p1 = new Person();
        p1.setDepartment(new Department("pA"));
        Person clone = (Person)p1.clone();
        System.out.println(clone.getDepartment() == p1.getDepartment());

3.1 在覆盖的clone方法中重新设置

@Override
    protected Object clone() throws CloneNotSupportedException {
        Person res = null;
        res = (Person)super.clone();
        Department dept = (Department)this.getDepartment().clone();
        res.setDepartment(dept);
        return res;
    }

但是同样存在问题:如果引用型成员变量太多,也要一个个设置。

3.2 使用序列化

利用字节输出流,字节输入流,对象输出流,对象输入流

public Object deepClone() {
        ByteArrayOutputStream bos = null;
        ObjectOutputStream oos = null;
        ByteArrayInputStream bis = null;
        ObjectInputStream ois = null;


        try {
            bos = new ByteArrayOutputStream();
            oos = new ObjectOutputStream(bos);
            oos.writeObject(this);

            bis = new ByteArrayInputStream(bos.toByteArray());
            ois = new ObjectInputStream(bis);
            Object o = ois.readObject();

            return o;
        } catch (Exception e) {
            e.printStackTrace();
            return null;
        }
        finally {
            try {
                bos.close();
                oos.close();
                bis.close();
                ois.close();
            } catch (IOException e) {
                e.printStackTrace();
            }

        }
    }

test:

Person2 p2 = new Person2();
        p2.setDepartment(new Department("abc"));
        Person2 o = (Person2)p2.deepClone();
        System.out.println(o);
        System.out.println(p2);
        System.out.println(o.getDepartment() == p2.getDepartment());

note : 利用序列化深拷贝的成员都要实现serilizable接口


以上是关于设计模式 原型模式的主要内容,如果未能解决你的问题,请参考以下文章

设计模式之原型模式(Prototype)详解及代码示例

设计模式课程 设计模式精讲 9-2 原型模式coding

设计模式--原型模式

设计模式原型模式

Java设计模式----原型模式

设计模式--------原型模式