继续浏览精彩内容
慕课网APP
程序员的梦工厂
打开
继续
感谢您的支持,我会继续努力的
赞赏金额会直接到老师账户
将二维码发送给自己后长按识别
微信支付
支付宝支付

设计模式-原型模式

mySoul__
关注TA
已关注
手记 103
粉丝 68
获赞 279

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

电子账单

即,使用电子账单

// 广告信模板
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内部,将该对象引用的对象,再次进行拷贝即可。

应用

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

打开App,阅读手记
0人推荐
发表评论
随时随地看视频慕课网APP