设计模式(七)—原型模式

最后更新于:2022-04-01 16:26:07

**英文名称:Prototype Pattern** **定义**:用原型实例指定创建对象的种类,并且通过拷贝这些原型创建新的对象。 原型模式的核心就是一个clone方法,通过该方法进行对象的拷贝,java提供了一个Cloneable接口,来标示这个对象是可拷贝的。 **一个例子:** 一个银行,定时给不同的用户发送特定的邮件。 AdvTemplate类,advSubject(标题)advContext(内容) Mail receiver(接收者),subject(名称),appellation(称谓),context(内容),tail(版本信息). **![](https://docs.gechiui.com/gc-content/uploads/sites/kancloud/2016-06-06_57553409923ab.jpg)** ~~~ public class PrototypeTest { public static void main(String[] args) { //将模板放入到Mail实例中,发送邮件。 Mail mail = new Mail(new AdvTemplate()); for(int i=0;i<10000;i++){ Mail cloneMail = (Mail) mail.clone(); cloneMail.setAppellation(getRandString(5)+"先生:您好!\n"); cloneMail.setReceiver(getRandString(5)+".com\n"); sendMail(mail); } } //发送信息,并返回已发送成功的回执。 public static void sendMail(Mail mail){ System.out.println("标题:"+mail.getSubject()+"\t 内容:"+mail.getContext()+"\t"+"发送成功!\n"); } //随机产生一些接收者和称谓信息。 public static String getRandString(int length){ String source = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz"; Random random = new Random(); StringBuffer sb = new StringBuffer(); while(length-- != 0){ sb.append(source.charAt(random.nextInt(source.length()))); } return sb.toString(); } } class AdvTemplate{ private String advSubject="某银行元旦信用卡抽奖活动"; private String advContext="元旦抽奖活动,只要刷卡就送你一个大红包!"; public String getAdvSubject() { return advSubject; } public String getAdvContext() { return advContext; } } class Mail implements Cloneable{ //收件人 private String receiver; //名称 private String subject; //称谓 private String appellation; //内容 private String context; //版本信息 private String tail; public Mail(AdvTemplate advTemplate) { this.subject = advTemplate.getAdvSubject(); this.context = advTemplate.getAdvContext(); } 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 getContext() { return context; } public void setContext(String context) { this.context = context; } public String getTail() { return tail; } public void setTail(String tail) { this.tail = tail; } //重写Object类中的clone方法。 @Override protected Object clone(){ Mail mail = null; try { mail = (Mail) super.clone(); } catch (Exception e) { e.printStackTrace(); } return mail; } } ~~~ **原型模型优点:** 性能优良,---原型模型是在内存二进制流的拷贝,比直接new一个对象性能好很多,特别是在循环体内产生大量的对象时,原型模式可以更好的体现其优点。 逃避构造函数的约束,--直接从内存中拷贝,构造函数是不会执行的。 **原型模式的注意事项** 1、构造函数不会被执行。 2、浅拷贝和深拷贝 **浅拷贝** --|Object类提供的方法clone只是拷贝本对象,其对象内部的数组、引用对象等都不拷贝,还是指向原声对象的内部元素地址,这种拷贝叫做浅拷贝。 **深拷贝** --|两个对象之间没有任何瓜葛,你修改你的,我修改我的。互不影响,这种拷贝叫做深拷贝。 3、clone和final是冤家。 出现final的对象或变量,不能clone。 ~~~ public class Prototype { public static void main(String[] args) { //创建一个对象 MyClone myClone = new MyClone(); myClone.setArrayList("lzl"); //将该对象clone。 MyClone clone2 = (MyClone) myClone.clone(); clone2.setArrayList("xy"); //输出原对象的结果。 System.out.println("原对象...."+myClone.getArrayList()); //输出拷贝后的结果。 System.out.println("拷贝结果...."+clone2.getArrayList()); } } class MyClone implements Cloneable{ private ArrayList<String> arrayList = new ArrayList<String>(); @SuppressWarnings("unchecked") @Override public MyClone clone(){ MyClone myClone =null; try { myClone = (MyClone) super.clone(); //把私有对象也进行拷贝。做到深拷贝的效果 myClone.arrayList = (ArrayList<String>) this.arrayList.clone(); } catch (Exception e) { e.printStackTrace(); } return myClone; } public ArrayList<String> getArrayList() { return arrayList; } public void setArrayList(String name) { this.arrayList.add(name); } } ~~~
';