原型模式定义:用原型实例指定创建对象的种类,并且通过拷贝这些原型创建新的对象。
首先了解原型模式之前我们先理解一下Cloneable这个类:
Cloneable接口没有定义成员。它通常用于指明被创建的一个允许对对象进行位复制(也就是对象副本)的类。如果试图用一个不支持Cloneable接口的类调用clone( )方法,将引发一个CloneNotSupportedException异常。当一个副本被创建时,并没有调用被复制对象的构造函数。副本仅仅是原对象的一个简单精确的拷贝。
原型模式的优点:
- 性能优良,原型模式是在内存二进制流的拷贝,要比直接new一个对象性能好很多,特别是要在一个循环体内产生大量的对象时,原型模式可以更好地体现其优点
- 逃避构造函数的约束,这也是它的缺点,直接在内存中拷贝,构造函数是不会被执行
原型模式使用场景:
- 资源优化场景
- 性能和安全要求的场景
- 一个对象多个修改者的场景
/** * @author Lin * @Date 2018/1/5. */ public class Mail implements Cloneable{ /** * 收件人 */ private String receiver; /** * 邮件名称 */ private String subject; /** * 称谓 */ private String appellation; /** * 邮件内容 */ private String content; /** * 邮件尾部信息 */ private String tail; public Mail(AdvTemplate advTemplate){ this.content = advTemplate.getAdvContent(); this.subject = advTemplate.getAdvSubject(); } @Override protected Mail clone() { Mail mail = null; try{ mail = (Mail) super.clone(); }catch (CloneNotSupportedException e){ 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 String getAppellation() { return appellation; } public void setAppellation(String appellation) { this.appellation = appellation; } public String getContent() { return content; } public void setContent(String content) { this.content = content; } public String getTail() { return tail; } public void setTail(String tail) { this.tail = tail; } }
/** * @author Lin * @Date 2018/1/5. */ public class AdvTemplate { /** * 广告信名称 */ private String advSubject = "xx银行过年信用卡抽奖活动"; /** * 广告信内容 */ private String advContent = "国庆抽奖活动通知:只要你刷卡就送你一个亿。。。。"; public String getAdvSubject() { return advSubject; } public String getAdvContent() { return advContent; } }
import java.util.Random; /** * @author Lin * @Date 2018/1/5. */ 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("xx银行版权所有"); while (i < MAX_COUNT){ Mail mailClone = mail.clone(); mailClone.setAppellation(getRandString(5) + "先生(女士)"); mailClone.setReceiver(getRandString(5) + "@" + getRandString(8) + ".com"); sendMail(mailClone); i++; } } public static void sendMail(Mail mail){ System.out.println("标题:" + mail.getSubject() + "\t收件人:" + mail.getReceiver() + "\t.....发送成功!"); } public static String getRandString(int maxLength){ String source = "abcdefghijklnmopqrstuvwxyzABCDEFGHIJKLNMOPQRSTUVWXYZ"; 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(); } }