设计模式_原型模式


Prototype Patttern 

    specify the kinds of objects to create using a prototypical instance,and create new objects by coping this prototype.(用原型实例实例指定创建对象的种类,并且通过拷贝这个原型创建新的对象)
实现Clonable接口,实现clone方法即可。

例子

发邮件
public class AdvTemplate {
 private String advSubject = "XX银行抽奖活动";  //广告名称
 private String advContext = "只要刷卡就就送你10Q币"; //广告内容
 public String getAdvSubject() {
  return advSubject;
 }
 public String getAdvContext() {
  return advContext;
 }
}

public class Mail implements Cloneable{
 
 private String receiver;
 private String subject;
 private String appellation;
 private String context;
 private String tail;
 
 public Mail(AdvTemplate advTemplate){
  this.context=advTemplate.getAdvContext();
  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 getContext() {
  return context;
 }

 public void setContext(String context) {
  this.context = context;
 }

 public String getTail() {
  return tail;
 }

 public void setTail(String tail) {
  this.tail = tail;
 }
}
public class ClientI {
 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 cloneMail=mail.clone();   //在这里拷贝
   cloneMail.setAppellation(getRandString(5)+"先生(女生)");
   cloneMail.setReceiver(getRandString(5)+"@"+getRandString(8)+".com");
   sendMail(cloneMail);
   i++;
  }
 }
 
 private static void sendMail(Mail mail) {
  System.out.println("标题:"+mail.getSubject()+"\t 收件人:"+mail.getReceiver()+"发送成功!");
 }

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

特点

    1.克隆时构造函数不会执行 
    2.Object中的clone()方法为浅拷贝,只拷贝对象本身,其内部的数组,引用对象等不拷贝,还是指向原生对象的内部元素地址。 俩个对象共享一个私有变量,不安全。
public class Thing implements Cloneable{
 private ArrayList<String> list=new ArrayList<String>();
 
 public Thing(){
  System.out.println("执行了构造方法");
 }
 /*浅拷贝:俩个对象共享了一个私有变量,指向原生对象的内部元素地址,不安全
  *深拷贝:thing.list=(ArrayList<String>) this.list.clone();
  *满足俩个条件时才不会被拷贝:1.类的成员变量    2.必须是一个可变的引用对象,而不是一个原始类型或不可变对象
  */
 @Override
 protected Thing clone(){
  Thing thing=null;
  try {
   thing=(Thing) super.clone();
   thing.list=(ArrayList<String>) this.list.clone();
  //没有这句的结果不一样
  } catch (CloneNotSupportedException e) {
   e.printStackTrace();
  }
  return thing;
 }
 
 public void setValue(String value){
  list.add(value);
 }
 
 public ArrayList<String> getValue(){
  return this.list;
 }
}
 public static void main(String[] args) {
   Thing thing=new Thing();
   thing.setValue("LOL");
   Thing thingClone=thing.clone();
   thingClone.setValue("CF");
   System.out.println(thing.getValue());
 }
}

结果:不管是浅拷贝还是深拷贝,构造函数只执行一次,浅拷贝会改变原来的集合值,而深拷贝不会,俩个独立。

性能优良

    内存二进制流的拷贝,比new性能好很多,特别是需要产生大量对象时
    逃避构造函数的约束,构造函数=约束

使用场景

    产生一个对象需要非常繁琐的数据准备或访问权限时,可以使用
    缺点使用,当一个对象需要多个对象访问时,而且各个调用者可以修改其值时(不得不说,任何事物不能看的太窄了,缺点即优点)
    

悟:从内存中复制对象,分为浅复制和深复制。不安全,要看使用场合。

我是菜鸟,我在路上。
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值