设计模式-原型模式

本文探讨了设计模式中的原型模式,通过实例演示如何利用原型模式和多线程技术优化邮件发送流程,提高效率。文章详细介绍了原型模式的原理,并展示了如何在Java中实现原型模式,包括使用Cloneable接口进行浅拷贝和深拷贝,以及如何在多线程环境中避免对象状态污染。

设计模式-原型模式 用原型实例指定创建对象的种类,通过拷贝这些原型创建新的对象。

电子账单

即,使用电子账单

// 广告信模板
public class AdvTemplate {
	// 广告信名称
	private String advSubject = "XX活动";
	// 广告内容
	private String advContext = "XX活动";
	// 取得广告名称
	public String getAdvSubject(){
		return this.advSubject;
	}
	// 取得广告信内容
	public String getAdvContext(){
		return this.advContext;
	}
}
复制代码
// 邮件
public class Mail {
	// 收件人
	private String receiver;
	// 邮件名称
	private String subject;
	// 称谓
	private String appellation;
	// 邮件内容
	private String contxt;
	// 邮件尾部
	private String tail;
	// 构造函数
	public Mail(AdvTemplate advTemplate){
		this.contxt = advTemplate.getAdvContext();
		this.subject = advTemplat.getAdvSubject()
	}
	// get set方法
	public String getReceiver(){
		return receiver;
	}
	public void setReceiver(String receiver){
		this.receiver = receiver;
	}
	public String getSubject(){
		return subject;
	}
	public void setSubject(String subject){
		this.subject = subject;
	}
	public String getApplation(){
		return applation;
	}
	public void setApplation(String applation){
		this.appellation = applation
	}
	public String getContxt(){
		return contxt;
	}
	public void setContxt(String contxt){
		this.contxt = contxt;
	}
	public String getTail(){
		return tail;
	}
	public void setTail(String tail){
		this.tail = tail;
	}
}
复制代码

最后绘制场景

public class Client {
	// 发送账单的数量
	private static int MAX_COUNT = 6;
	public static void main(String[] args){
		// 模拟发送邮件
		int i = 0;
		// 模板定义
		Mail mail = new Mail(new AdvTemplate());
		mail.setTail("  ");
		while(i < MAX_COUNT){
			mail.setAppllation(getRandString(5) + "先生(女士)");
			mail.setReceiver(getRandString(5) + "@" + mail.getRandString() + ".com");
			// 发送邮件
			sendMail(mail);
			i++;
		}
	}
	// 发送邮件
	public static void sendMail(Mail mail){
		System.out.println("标题" + mail.getSubject() + "发送成功");
	}
	// 获取指定长度的随机字符串
	public static String getRandString(int maxLength){
		String source = "abcdefghijklmnopqrstuvwxyz";
		// 缓冲区
		StringBuffer sb = new StringBuffer();
		// 随机数
		Random rand = new Random();
		// 进行循环
		for(int i = 0; i < maxLength; i++){
			// 进行随机取字符数
			sb.append(source.charAt(rand.nextlnt(source.length())));	// rand.nextInt()	生成伪随机数,放入到缓冲区内
		}
		return sb.toString();	// 返回生成的伪字符串
	}
}
复制代码

使用多线程改进

由于是一个线程发送邮件过慢,使用多线程解决问题。

增加一个Cloneable接口

关于克隆

克隆用途

关于Cloneable 接口,用途和Serializable一样为标记型接口,内部没有方法和属性,implements Cloneable 表示对象能被克隆,即能使用Object.clone()方法,

关于深浅拷贝

这个已经重复多次了。。。。。。。。。再js里已经重复了一次 浅拷贝,只单单拷贝本身,不拷贝引用。 深拷贝,完整的递归拷贝。

修改后的代码

public class Mail implements Cloneable {	// 继承自java本身就有的空接口,即Cloneable
	// 收件人
	private String receiver;
	// 邮件名称
	private String subject;
	// 称谓
	private String appellation;
	// 邮件内容
	private String contxt;
	// 邮件尾部
	private String tail;
	// 构造函数
	public Mail(AdvTemplate advTemplate){
		this.contxt = advTemplate.getAdvContext();
		this.subject = advTemplat.getAdvSubject()
	}
	// 下面进行浅拷贝,重写clone方法
	@Override
	public Mail clone(){
		Mail mail = null;
		try{
			mail = (Mail)super.clone();
		}catch(CloneNotSupportedException e){
			e.printStackTrace();
		}
		return mail;
	}
	// get set方法
	public String getReceiver(){
		return receiver;
	}
	public void setReceiver(String receiver){
		this.receiver = receiver;
	}
	public String getSubject(){
		return subject;
	}
	public void setSubject(String subject){
		this.subject = subject;
	}
	public String getApplation(){
		return applation;
	}
	public void setApplation(String applation){
		this.appellation = applation
	}
	public String getContxt(){
		return contxt;
	}
	public void setContxt(String contxt){
		this.contxt = contxt;
	}
	public String getTail(){
		return tail;
	}
	public void setTail(String tail){
		this.tail = tail;
	}
}
复制代码

然后修改场景类

public class Client {
	// 发送账单的数量
	private static int MAX_COUNT = 6;
	public static void main(String[] args){
		// 模拟发送邮件
		int i = 0;
		// 模板定义
		Mail mail = new Mail(new AdvTemplate());
		mail.setTail("  ");
		while(i < MAX_COUNT){
			Mail cloneMail = mail.clone();
			cloneMail.setAppllation(getRandString(5) + "先生(女士)");
			cloneMail.setReceiver(getRandString(5) + "@" + mail.getRandString() + ".com");
			// 发送邮件
			sendMail(cloneMail );
			i++;
		}
	}
	// 发送邮件
	public static void sendMail(Mail mail){
		System.out.println("标题" + mail.getSubject() + "发送成功");
	}
	// 获取指定长度的随机字符串
	public static String getRandString(int maxLength){
		String source = "abcdefghijklmnopqrstuvwxyz";
		// 缓冲区
		StringBuffer sb = new StringBuffer();
		// 随机数
		Random rand = new Random();
		// 进行循环
		for(int i = 0; i < maxLength; i++){
			// 进行随机取字符数
			sb.append(source.charAt(rand.nextlnt(source.length())));	// rand.nextInt()	生成伪随机数,放入到缓冲区内
		}
		return sb.toString();	// 返回生成的伪字符串
	}
}
复制代码

使用拷贝,将sendMail放入线程池里,每次拷贝一个对象,然后将对象放入sendMail,然后将sendMail放入线程里,每次运行一个线程,拷贝一个对象,这样解决,一个线程还未发送完成邮件的时候,就传入的对象被修改的问题。

最后 深拷贝

实现深拷贝 在clone内部,将该对象引用的对象,再次进行拷贝即可。

应用

打飞机游戏中,主飞机,使用单例模式,其余飞机,使用原型模式,以一架飞机为原型,生成多个飞机。后者使用深拷贝。

转载于:https://juejin.im/post/5c03e2e95188252f170e237a

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值