java 原型模式之深拷贝和浅拷贝

2019-04-16 11:29:49 浏览数 (1)

在没有开始学习,原型模式之前我们先来看一下Java中的深拷贝和浅拷贝

代码语言:javascript复制
package prototype.pattern;

import java.util.ArrayList;

public class Thing implements Cloneable{
	 private   ArrayList<String> list = new ArrayList<String>();
     public Thing(){
    	 System.out.println("产生一个对象  ");
     }
     
     public Thing clone(){
    	 Thing thing = null;
    	 try {
			thing = (Thing) super.clone();
			
			this.list = (ArrayList<String>) this.list.clone();//你可以通过注掉这一行代码来看深度拷贝和浅拷贝输出结果不同
		} catch (CloneNotSupportedException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
	
    	 return thing;
     }
     
     public void setValue(String value){
    	 this.list.add(value);
     }
     
     public ArrayList<String> getValue(){
    	 return this.list;
     }
     public static void main(String[] args) {
		Thing t = new Thing();
		t.setValue("张三");
		Thing clonething = t.clone();
		clonething.setValue("李四");
		System.out.println(t.getValue());
	}
}
代码语言:javascript复制
其Object类提供的clone方法只拷贝本对象,对其内部的数组和引用对象都不拷贝。
代码语言:javascript复制
原形模式是一种非常简单的模式,其核心就是实现了Cloneable接口的方法才有可能被拷贝,这个接口起到一个表知作用。


原型模式的优点:
1:性能优良  原型模式是内存的二进制流的拷贝,要比直接new一个对象性能好很多,特别是在一个循环体内产生大量的对象时。
2:逃避构造函数的约束:直接从内存中拷贝,构造函数不会被执行


使用场合:
资源优化场景
类初始化时需要耗费非常多的资源,这些资源包括数据,硬件资源。
性能和安全要求
通过new产生一个对象需要非常繁琐的数据准备和访问权限,则可以使用原形模式。
一个对象多个修改者
一个对象需要提供给其它对象访问,而且各个调用者可能都需要修改其值时,可以考虑使用原形拷贝多个对象供调用者使用。
代码语言:javascript复制
</pre><pre name="code" class="java">
代码语言:javascript复制
<pre name="code" class="java">package prototype.pattern;

public class Adtemplate {
	//邮件主题
    private String adSubject = "xxxx公司举行周年纪念日";
    //邮件内容
    private  String adContext = "活动通知,只要刷卡,就送钱800w。。。。";
    
	public String getAdSubject() {
		return adSubject;
	}
 
	public String getAdContext() {
		return adContext;
	}
	 
	
    
}
代码语言:javascript复制
package prototype.pattern;

public class Mail implements Cloneable{
	private String receiver;

	private String subject;

	private String appelation;

	private String context;

	private String tail;

	public Mail(Adtemplate adt) {
		this.subject = adt.getAdSubject();
		this.context = adt.getAdContext();
	}
	
	@Override
	public Mail clone(){
		Mail mail = null;
		try {
			mail = (Mail) super.clone();
		} catch (CloneNotSupportedException e) {
			e.printStackTrace();
		}
		return mail;
		
	}

	public String getAppelation() {
		return appelation;
	}

	public String getContext() {
		return context;
	}

	public String getReceiver() {
		return receiver;
	}

	public String getSubject() {
		return subject;
	}

	public String getTail() {
		return tail;
	}

	public void setAppelation(String appelation) {
		this.appelation = appelation;
	}

	public void setContext(String context) {
		this.context = context;
	}

	public void setReceiver(String receiver) {
		this.receiver = receiver;
	}

	public void setSubject(String subject) {
		this.subject = subject;
	}

	public void setTail(String tail) {
		this.tail = tail;
	}
}
代码语言:javascript复制
package prototype.pattern;

import java.util.Random;

public class Client {
	private  final static  int MAX_COUNT = 6;
    public static void main(String[] args) {
		//模拟发送邮件
    	int i = 0;
    	
    	Mail mail = new Mail(new Adtemplate());
    	mail.setTail("某某公司制造 ");
    	
    	while(i<MAX_COUNT){
    		Mail clonemail = mail.clone();
    		clonemail.setAppelation(getRandString(5) " 先生 ");
    		clonemail.setReceiver(getRandString(5) " @" getRandString(8) " .com");
    		
    		sendMail(clonemail);
    		i  ;
    	}
	}
	private static void sendMail(Mail mail) {
         System.out.println("标题  : " mail.getSubject() "t收件人" mail.getReceiver() "t ....发送成功");		
	}
	private static String getRandString(int length) {
		String source = "abcdefghijklmnopqrstuvwxyz";
		StringBuffer sb = new StringBuffer();
		Random rand = new Random();
		for(int i=0;i<length;i  ){
			sb.append(source.charAt(rand.nextInt(source.length())));
		}
		return sb.toString();
	}
}
代码语言:javascript复制

0 人点赞