设计模式--原型模式

                  设计模式--原型模式


 

银行的电子账单、广告信:

特点:量大、时间要求紧

思考如何设计

设计模式--原型模式


Mail 

import java.util.Random;

public class Mail {
	private String receiver;
	private String subject;
	private String content;
	private String tail;

	public Mail(EventTemplate et) {
		this.tail = et.geteventContent();
		this.subject = et.geteventSubject();
	}

	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 void setContent(String content) {
		this.content = content;
	}

	public String getContent() {
		return content;
	}

	public String getTail() {
		return tail;
	}

	public void setTail(String tail) {
		this.tail = tail;
	}

}

EventTemplate  


public class EventTemplate {
	private String eventSubject, eventContent;

	public EventTemplate(String eventSubject, String eventContent) {
		this.eventSubject = eventSubject;
		this.eventContent = eventContent;
	}

	public String geteventSubject() {
		return eventSubject;
	}

	public String geteventContent() {
		return eventContent;
	}
}


MainTest 

import java.util.Random;

public class MainTest {
	public static void main(String[] args) {
		int i = 0;
		int MAX_COUNT = 10;
		EventTemplate et = new EventTemplate("9月份信用卡账单", "国庆抽奖活动...");

		Mail mail = new Mail(et);

		while (i < MAX_COUNT) {
			// 以下是每封邮件不同的地方
			
			mail.setContent(getRandString(5) + ",先生(女士):你的信用卡账单..."
					+ mail.getTail());
			mail.setReceiver(getRandString(5) + "@" + getRandString(8) + ".com");
			// 然后发送邮件
			sendMail(mail);
			i++;
		}

	}

	public static String getRandString(int maxLength) {
		String source = "abcdefghijklmnopqrskuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ";
		StringBuffer sb = new StringBuffer();
		Random rand = new Random();
		for (int i = 0; i < maxLength; i++) {
			sb.append(source.charAt(rand.nextInt(source.length())));
		}
		return sb.toString();
	}

	public static void sendMail(Mail mail) {
		System.out.println("标题:" + mail.getSubject() + "\t收件人:"
				+ mail.getReceiver() + "\t内容:" + mail.getContent()
				+ "\t....发送成功!");
	}

}


这种设计有啥问题

500w*0.1s=50ws

解决方式:

SendMail多线程(存在线程不安全)
 

原型模式原理

设计模式--原型模式

原型模式:通过复制现有实例来创建新的实例,无须知道相应类的信息


 

原型模式示例代码讲解

示例项目类结构

设计模式--原型模式


Mail 

import java.util.ArrayList;
import java.util.Random;

public class Mail implements Cloneable {
	private String receiver;
	private String subject;
	private String content;
	private String tail;
	private ArrayList<String> ars;
	public Mail(EventTemplate et) {
		this.tail = et.geteventContent();
		this.subject = et.geteventSubject();
	
	}

	@Override
	public Mail clone() {
		Mail mail = null;
		try {
			mail = (Mail) super.clone();
			mail.ars = (ArrayList<String>)this.ars.clone();  //深拷贝
		} catch (CloneNotSupportedException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		return mail;
	}

	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 void setContent(String content) {
		this.content = content;
	}

	public String getContent() {
		return content;
	}

	public String getTail() {
		return tail;
	}

	public void setTail(String tail) {
		this.tail = tail;
	}

}


 MainTest

import java.util.Random;


public class MainTest {
	public static void main(String[] args) {
		int i = 0;
		int MAX_COUNT = 10;
		EventTemplate et = new EventTemplate("9月份信用卡账单", "国庆抽奖活动...");

		Mail mail = new Mail(et);

		while (i < MAX_COUNT) {
			// 以下是每封邮件不同的地方
			Mail cloneMail = mail.clone();
			cloneMail.setContent(getRandString(5) + ",先生(女士):你的信用卡账单..."
					+ mail.getTail());
			cloneMail.setReceiver(getRandString(5) + "@" + getRandString(8)
					+ ".com");
			// 然后发送邮件
			sendMail(cloneMail);
			i++;
		}

	}

	public static String getRandString(int maxLength) {
		String source = "abcdefghijklmnopqrskuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ";
		StringBuffer sb = new StringBuffer();
		Random rand = new Random();
		for (int i = 0; i < maxLength; i++) {
			sb.append(source.charAt(rand.nextInt(source.length())));
		}
		return sb.toString();
	}

	public static void sendMail(Mail mail) {
		System.out.println("标题:" + mail.getSubject() + "\t收件人:"
				+ mail.getReceiver() + "\t内容:" + mail.getContent()
				+ "\t....发送成功!");
	}

}


原型模式关键点

原型模式原理

原型模式:通过复制现有实例来创建新的实例,无须知道相应类的信息

注意事项:

  使用原型模式复制对象不会调用类的构造方法。所以,单例模式与原型模式是冲突的,在使用时要特别注意。(还有final类)

  Object类的clone方法只会拷贝对象中的基本的数据类型,对于数组、容器对象、引用对象等都不会拷贝,这就是浅拷贝。如果要实现深拷贝,必须将原型模式中的数组、容器对象、引用对象等另行拷贝。


原型模式适用场合

适用场合:

  复制对象的结构与数据

  希望对目标对象的修改不影响既有的原型对象

  创建对象成本较大的情况下