【设计模式学习笔记】原型模式

版权声明:本文为博主原创文章。 https://blog.csdn.net/baidu_30325009/article/details/85028459

原型模式,估计这是最简单的模式了。这个模式可以用于创建重复的对象,同时又能保证性能。这种类型的设计模式属于创建型模式,它提供了一种创建对象的最佳方式。额外说一句,这里的创建对象只是浅拷贝的。

没什么好说的,直接看程序吧。要实现对象的浅拷贝,需要让待拷贝对象实现Cloneable接口。

1.1 浅拷贝

package prototype;


public class Model implements Cloneable {
	private String name;
	private String price;
    private A a = new A("a");


    public String getName() {
        return name;
    }

    public String getPrice() {
        return price;
    }

    public A getA() {
        return a;
    }

    protected Object clone() {
		try {
			return super.clone();
		} catch (CloneNotSupportedException e) {
			e.printStackTrace();
			return null;
		}
	}

	public Model(String name, String price) {
		super();
		this.name = name;
		this.price = price;
	}


}

1.2 测试

package prototype;

import java.io.*;

public class Test {
	public static void main(String[] args) {
		// 浅拷贝 Nikola Zhang  【2018/12/14 0014 20:51】
	  Model modelA = new Model("AAA","1111");
		Model modelB = (Model)modelA.clone();

		System.out.println(modelA);
		System.out.println(modelB);
		System.out.println(modelA.getA());
		System.out.println(modelB.getA());
		System.out.println(modelB.getPrice());
		System.out.println(modelB.getName());
  }
}

1.3 结果

在这里插入图片描述

根据结果截图,可以看到引用类型对象modelA,modelB的地址是不同的。但内部的引用类型A地址确实相同的。
这就引出了一个额外的话题,深拷贝。深拷贝可以通过实现Cloneable接口实现,也可以通过实现Serializable接口实现。
代码如下:

2.1 深拷贝

package prototype;


import java.io.Serializable;

public class ModelS implements Serializable {
	private String name;
	private String price;
    private A a = new A("a");


    public String getName() {
        return name;
    }

    public String getPrice() {
        return price;
    }

    public A getA() {
        return a;
    }

	public ModelS(String name, String price) {
		super();
		this.name = name;
		this.price = price;
	}


}

2.2 测试深拷贝

package prototype;

import java.io.*;

public class Test {
	public static void main(String[] args) {
		// 浅拷贝 Nikola Zhang  【2018/12/14 0014 20:51】
	    Model modelA = new Model("AAA","1111");
		Model modelB = (Model)modelA.clone();

		System.out.println(modelA);
		System.out.println(modelB);
		System.out.println(modelA.getA());
		System.out.println(modelB.getA());
		System.out.println(modelB.getPrice());
		System.out.println(modelB.getName());

        // 深拷贝 Nikola Zhang  【2018/12/14 0014 20:51】
		ModelS modelS = new ModelS("SSS","2222");
        try {
            ByteArrayOutputStream bos=new ByteArrayOutputStream();
            ObjectOutputStream oos=new ObjectOutputStream(bos);
            oos.writeObject(modelS);
            oos.flush();
            ObjectInputStream ois=new ObjectInputStream(new ByteArrayInputStream(bos.toByteArray()));
            ModelS modelS1 =  (ModelS)ois.readObject();
            System.out.println(modelS.getA());
            System.out.println(modelS1.getA());
            ois.close();
            oos.close();
            bos.close();
        } catch (IOException e) {
            e.printStackTrace();
        } catch (ClassNotFoundException e) {
            e.printStackTrace();
        }

    }

}

需要注意的是,ModelS中的引用类型必须实现Serializable接口,否则会报错。

2.3 结果

在这里插入图片描述
可以看到,ModelS中的引用类型的地址经过深拷贝后是不同的。当你更改其中一个的value后,另一个对象的value自然是不会改变。

参考

【菜鸟教程】:http://www.runoob.com/design-pattern/prototype-pattern.html

猜你喜欢

转载自blog.csdn.net/baidu_30325009/article/details/85028459