对象创建型模式之原型模式

    应用场景:Ctrl+C Ctrl+V,Struts中保证线程的安全性,Action 对象的创建使用了原型模式,访问一个已经存在Action对象时将通过克隆的方式创建出一个新的对象,从而保证其中定义的变量无须进行加锁实现同步,每个Action中都有自己的成员变量,彼岸Struts1因使用单利模式而导致的并发和同步问题。Spring框架中使用原型模式来创建bean实例

    原型模式结构较为简单,它是一种特殊的创建型模式,当需要创建大量相同或者相似对象时,可以通过对一个已有对象的复制获取更多的对象。

    在软件系统中,有时候需要多次创建某一类型的对象,为了简化创建过程,可以只需要创建一个对象,然后再通过克隆的方式复制出多个相同的对象,这就是原型模式的设计思想。

    在软件系统中,有些对象的创建工程较为复杂,而且有时候需要频繁创建,原型模式通过给出一个原型对象来指明所要创建对象的类型,然后用复制这个原型对象的办法创建出更多同类型的对象,这就是原型模式的意图所在。

    定义:原型模式是一种对象创建型模式,用原型实例指定创建对象的种类,并且通过复制这些原型创建新的对象。

模式结构图:


深克隆和浅克隆:

浅克隆,被复制对象所有的变量都具有原来的对象相同的值,而所有的对其他对象的引用仍然指向原来的对象。换句话说,就是指浅克隆仅仅复制所考虑的对象,而不复制它所引用的成员对象。


深克隆,在深克隆中被复制对象的所有普通成员变量也都含有与原来的对象相同的值,除去那些引用其他对象的变量。换句话说,深克隆把要复制的对象所引用的对象都复制了一遍,除了对象本身被复制之外,对象包含的引用也被复制,也就是其中的成员对象也将被复制。


代码:

客户端:

package com.prototypepattern.hing;

import java.io.IOException;

public class Client {

	public static void main(String[] args) {
		// TODO Auto-generated method stub
		//浅克隆
		Attachment attachment = new Attachment();
		Email e = new Email(attachment);
		Email e1 = (Email)e.clone();
		System.out.println(e == e1);
		System.out.println(e.getAttachment() == e1.getAttachment());
		//深克隆
		Email1 de = new Email1();
		Email1 de1 = null;
		try {
			de1 = (Email1)de.deepClone();
		} catch (ClassNotFoundException e2) {
			// TODO Auto-generated catch block
			e2.printStackTrace();
		} catch (IOException e2) {
			// TODO Auto-generated catch block
			e2.printStackTrace();
		}
		System.out.println(de == de1);
		System.out.println(de.getAttachment() == de1.getAttachment());
	}

}


原型类(浅):

package com.prototypepattern.hing;

public class Email implements Cloneable{
	private Attachment attachment = null;
	public Attachment getAttachment() {
		return attachment;
	}
	public void setAttachment(Attachment attachment) {
		this.attachment = attachment;
	}
	public Email(Attachment attachment) {
		this.attachment=attachment;
	}
	public Object clone() {
		Email clone = null;
		try {
			clone = (Email)super.clone();
		} catch (CloneNotSupportedException e) {
			// TODO Auto-generated catch block
			System.out.println("克隆失败!");
		}
		return clone;
	}
	public void display() {
		System.out.println("查看邮件!");
	}
}

原型类(深):

package com.prototypepattern.hing;

import java.io.*;

public class Email1 implements Serializable{
	private Attachment attachment = null;
	public Email1() {
		this.attachment = new Attachment();
	}
	public Attachment getAttachment() {
		return attachment;
	}
	public void setAttachment(Attachment attachment) {
		this.attachment = attachment;
	}
	
	public Object deepClone() throws IOException, ClassNotFoundException, OptionalDataException{
		ByteArrayOutputStream bao = new ByteArrayOutputStream();
		ObjectOutputStream oos = new ObjectOutputStream(bao);
		oos.writeObject(this);
		
		ByteArrayInputStream bis = new ByteArrayInputStream(bao.toByteArray());
		ObjectInputStream ois = new ObjectInputStream(bis);
		return (ois.readObject());
	}
	public void display() {
		System.out.println("查看邮件!");
	}
}

被引用类:

package com.prototypepattern.hing;

import java.io.Serializable;

public class Attachment  implements Serializable{
	public void download() {
		System.out.println("下载附件!");
	}
}

运行结果:


总结:对深浅拷贝的理解可以说是本设计模式的核心,浅克隆通过JAVA自己的Cloneable接口的实现来是实现的,深克隆中是使用了序列化的方式实现的

科普:序列化(Serialization)是将对象的状态信息转换为可以存储或传输的形式的过程。一般将一个对象存储至一个存储媒介,比如档案、记忆缓冲或者流中,在网络传输过程中,可以是字节或是XML等格式。而字节或XML编码格式还可以还原完全相等的对象。这个相反的过程又称为反序列化。


猜你喜欢

转载自blog.csdn.net/qq_33977775/article/details/79453448