设计模式之原型模式

什么是原型模式

用已经创建的实例作为原型,通过复制该原型来创建新的对象.就像名人的影分身术一样简单.
在这里插入图片描述

深克隆与浅克隆

  • 浅克隆
    如果原型对象的成员变量是值类型(八大基本类型,byte,short,int,long,char,double,float,boolean).那么就直接复制,如果是复杂的类型,(枚举,String,对象)就只复制对应的内存地址。
  • 深克隆
    就是什么都是单独的!全部复制,然后各自独立。你修改克隆对象对于原型对象没有丝毫影响,完全的影分身!

原型模式的结构

在这里插入图片描述
原型模式包含三个主要角色:

  • 抽象原则类: 具体原型对象必须实现的接口
  • 具体原则类: 是可复制的对象,实现了抽象原则类的clone()方法
  • 访问类: 使用具体原则类的clone()方法来克隆对象
//具体原型类
class Realizetype implements Cloneable
{
    Realizetype()
    {
        System.out.println("具体原型创建成功!");
    }
    public Object clone() throws CloneNotSupportedException
    {
        System.out.println("具体原型复制成功!");
        return (Realizetype)super.clone();
    }
}
//原型模式的测试类
public class PrototypeTest
{
    public static void main(String[] args)throws CloneNotSupportedException
    {
        Realizetype obj1=new Realizetype();
        Realizetype obj2=(Realizetype)obj1.clone();
        System.out.println("obj1==obj2?"+(obj1==obj2));
    }
}

打印结果如下:

具体原型创建成功!
具体原型复制成功!
obj1==obj2?false

这里的Cloneable就是抽象原则类,提供了浅克隆方法.

浅克隆调用java的clone()方法,而深克隆通过序列化(Serialization)等方式来进行。
将附件类进行序列化.

package prototypePattern;
 
import java.io.Serializable;
  
public class Attachment_2 implements Serializable {
 private String name;	//附件名
 
public String getName() {
	return name;
}
 
public void setName(String name) {
	this.name = name;
}
 public void download() {
	 System.out.println("下载附件"+name);
 }
}

周报类也进行序列化:

package prototypePattern;
 
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.io.OutputStream;
import java.io.Serializable;
 
public class WeeklyLog_2 implements Serializable{
	
	private Attachment_2 attachment;
	private String date;
	private String name;
	private String content;
	public Attachment_2 getAttachment() {
		return attachment;
	}
	public void setAttachment(Attachment_2 attachment) {
		this.attachment = attachment;
	}
	public String getDate() {
		return date;
	}
	public void setDate(String date) {
		this.date = date;
	}
	public String getName() {
		return name;
	}
	public void setName(String name) {
		this.name = name;
	}
	public String getContent() {
		return content;
	}
	public void setContent(String content) {
		this.content = content;
	}
	//通过序列化进行深克隆
	public WeeklyLog_2 deepclone() throws Exception {
		//将对象写入流中,
		ByteArrayOutputStream bao = new ByteArrayOutputStream();
		ObjectOutputStream oos = new ObjectOutputStream(bao);
		oos.writeObject(this);
		//将对象取出来
		ByteArrayInputStream bi = new ByteArrayInputStream(bao.toByteArray());
		ObjectInputStream ois = new ObjectInputStream(bi);
		return (WeeklyLog_2)ois.readObject();
	}
}
package prototypePattern;                                                                                  
                                                                                                           
public class Client_2 {                                                                                      
    //测试类,客户端                                                                                              
	public static void main(String[] args) {                                                               
		WeeklyLog_2 log_1,log_2=null;                                                                             
		log_1 = new WeeklyLog_2();	//创建原型对象                                                               
		Attachment_2 attachment = new Attachment_2(); //创建附件对象                                                 
		log_1.setAttachment(attachment);	//将附件添加到周报种去                                                   
		try {
			log_2=log_1.deepclone();
		} catch (Exception e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}	//克隆周报                                                                     
		System.out.println("周报对象是否相同"+(log_1==log_2));                                                     
		System.out.println("附件对象是否相同"+(log_1.getAttachment()==log_2.getAttachment()));                     
	}                                                                                                      
}                                                                                                          

周报对象是否相同:false
附件对象是否相同:false

注: final 类型修饰的成员变量不能进行深拷贝

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值