原型模式(Prototype):用原型实例指定创建对象的种类,并且通过拷贝这些原型创建新的对象。
当我们已经拥有某个得来不易的宝贝时,往往我们会很想再“变”一些出来,即这个宝贝的“复制品”,这种方式简单又理想,谁都想要学会这项本事。不可能的事情!不过,这种手段在软件设计中是完全可以实现的,在OO中的原型模式就是这样基于思想的。
原型模式的适用场景:(摘录自《设计模式迷你手册》)
1、当要实例化的类是在运行时刻指定时,例如,通过动态装载;
2、为了避免创建一个与产品类层次平行的工厂类层次时;
3、当一个类的实例只能有几个不同状态组合中的一种时。建立相应数目的原型并克隆它们可能比每次用合适的状态手工实例化该类更方便一些。
通用类图如下:

在Java中,原型模式可以很简单地实现,只要实现Cloneable这个标识性的接口,再覆盖该接口中的clone()方法,即可“克隆”该实现类的任何一个对象。“克隆”的意思大家都明白,就是原封不动的复制。
由于Java中的最基类Object类中已经实现了Cloneable接口,故我们下面的代码例子中的会看不到上面类图中Prototype这个抽象类的影子。
具体代码如下:

测试结果:
蚂蚁 ...
蚂蚁 ...
在Java中有个浅拷贝和深拷贝之分,下面再给出个代码例子。
//原型02,成员变量中包含引用变量,得用深拷贝 
class ConcretePrototype02 implements Cloneable { 
  private String name; 
  private ArrayList<String> nameList = new ArrayList<String>();

public ConcretePrototype02(String name) { 
    this.name = name; 
    this.nameList.add(this.name); 
  } 
  //添加nameList中的对象 
  public void setName(String name) { 
    this.nameList.add(name); 
  } 
    
  public ArrayList<String> getNameList() { 
    return this.nameList; 
  } 
    
  //覆盖Object基类中的clone()方法,并扩大该方法的访问权限,具体化返回本类型 
  public ConcretePrototype02 clone() { 
    ConcretePrototype02 self = null; 
    try { 
      self = (ConcretePrototype02) super.clone(); 
      //以下这句是实现深拷贝的关键 
//      self.nameList = (ArrayList<String>) this.nameList.clone(); 
    } catch (CloneNotSupportedException e) { 
      e.printStackTrace(); 
    } 
    return self; 
  } 
}

//测试类 
public class Client { 
  public static void main(String[] args) { 
    ConcretePrototype02 prototype02 = new ConcretePrototype02("蚂蚁 ..."); 
    System.out.println(prototype02.getNameList()); 
     
    //通过clone获得一个拷贝 
    ConcretePrototype02 fromClone02 = prototype02.clone(); 
    fromClone02.setName("小蚂蚁 ..."); 
    System.out.println(fromClone02.getNameList()); 
    System.out.println(prototype02.getNameList()); 
  } 
}

测试结果:
拷贝之前的原型: [蚂蚁 ...]
拷贝得到的对象: [蚂蚁 ..., 小蚂蚁 ...]
拷贝之后的原型: [蚂蚁 ..., 小蚂蚁 ...]
发现拷贝之后原来的对象持有的ArrayList<String>类型的nameList引用会随着拷贝得到的fromClone对象执行了setName()方法而改变,这不是我们想要的结果,因为这意味着原型以及拷贝得到的对象共享同一个引用变量,这是线程不安全的。当我们去掉上面clone()方法中被注释的语句之后再测试,得到结果如下:
拷贝之前的原型: [蚂蚁 ...]
拷贝得到的对象: [蚂蚁 ..., 小蚂蚁 ...]
拷贝之后的原型: [蚂蚁 ...]
结果正确。其实,在Java中使用原型模式Prototype是相当简单的,只要记住几点注意点,就可以方便地实现该模式了。由于使用clone()方法来拷贝一个对象是从内存二进制流中进行IO读写,所以拷贝得到一个对象是不会执行该对象所对应类的构造函数的。总结如下:
1、构造函数不会被执行;
2、类的成员变量中若有引用类型的变量(数组也是一种对象),默认的clone()并不会对其进行拷贝,需自行提供深拷贝;
String类型与int、long、char等基本类型类似,默认地会被拷贝。
总之,Java中原型模式clone()方法对我们隐藏了许多细节,或者说必要操作,它的实现机制涉及到了反射、IO流操作、序列化等,只有弄清楚这一系列的知识才能更深入地理解这些相关的知识点。

//原型01,实现Cloneable接口并覆盖clone()方法 
class ConcretePrototype01 implements Cloneable { 
  private String name;

public ConcretePrototype01(String name) { 
    this.name = name; 
  } 
    
  public void getName() { 
    System.out.println(name); 
  } 
    
  //覆盖Object基类中的clone()方法,并扩大该方法的访问权限,具体化返回本类型 
  public ConcretePrototype01 clone() { 
    ConcretePrototype01 self = null; 
    try { 
      self = (ConcretePrototype01) super.clone(); 
    } catch (CloneNotSupportedException e) { 
      e.printStackTrace(); 
    } 
    return self; 
  } 
}

//测试类 
public class Client { 
  public static void main(String[] args) { 
    ConcretePrototype01 prototype01 = new ConcretePrototype01("蚂蚁 ..."); 
    prototype01.getName(); 
     
    //通过clone获得一个拷贝 
    ConcretePrototype01 fromClone01 = prototype01.clone(); 
    fromClone01.getName(); 
  } 
}

文章出处:http://haolloyin.blog.51cto.com/1177454/333442

转载于:https://www.cnblogs.com/andyboy/p/3445205.html

(Prototype)原型模式的Java实现(转)相关推荐

  1. JavaScript 面向对象 (prototype 原型模式)

    一. JavaScript 设计思想 1994年,网景公司(Netscape)发布了Navigator浏览器0.9版.这是历史上第一个比较成熟的网络浏览器,轰动一时.但是,这个版本的浏览器只能用来浏览 ...

  2. 设计模式-创建型模式-原型模式(Java)(创建重复对象)

    目录 原型模式 1 介绍 2 实现 具体实现步骤 原型模式 原型模式(Prototype Pattern)是⽤于创建重复的对象,同时⼜能保证性能.这种类型的设计模式属于创建型模式,它提供了⼀种创建对象 ...

  3. Prototype 原型模式

    一.意图:用原型实例指定创建对象的种类,并且通过拷贝这些原型创建新的对象.(Specify the kinds of objects to create using a prototypical in ...

  4. Prototype原型模式(创建型模式)

    1.原型模式解决的问题 现在有一个抽象的游戏设施建造系统,负责构建一个现代风格和古典风格的房屋和道路. 前提:抽象变化较慢,实现变化较快(不稳定) 整个抽象的游戏设施建造系统相对变化较慢,本例中只有一 ...

  5. java 设计模式 prototype_Java设计模式之Prototype原型模式

    一.场景描述 创建型模式中,从工厂方法模式,抽象工厂模式,到建造者模式,再到原型模式,我的理解是,创建对象的方式逐步从编码实现转向内存对象处理. 例如,在"仪器数据采集器"的子类/ ...

  6. 设计模式 - Prototype 原型模式

    微信搜索[三太子敖丙]关注这个贪财好色的程序员. 本文 GitHub https://github.com/JavaFamily 已收录,有一线大厂面试完整考点.资料以及我的系列文章. 前言 在设计模 ...

  7. prototype原型模式

    /** * 原型模式 Prototype * 用原型实例指定创建对象的种类,并通过拷贝这些原型创建新的对象 */ 需求: public class Resume { /** * 要求:一个简历类,必须 ...

  8. C++设计模式-Prototype原型模式

    作用: 用原型实例指定创建对象的种类,并且通过拷贝这些原型创建新的对象. Prototype模式提供了一个通过已存在对象进行新对象创建的接口(Clone), Clone()实现和具体的语言相关,在C+ ...

  9. c语言 prototype_(创建型模式)Prototype——原型模式

    1.意图 原型模式:用原型实例指定创建对象的种类,并且通过拷贝这些原型创建新的对象. 2.核心思想 通过给出一个原型对象来指明所要创建的对象的类型,然后用复制这个原型对象的方法创建出更多同类型的对象. ...

最新文章

  1. php投票系统制作,php简单的投票系统[原创]
  2. 计算机主机内部防尘装置,一种计算机主机用防尘装置的制作方法
  3. form-validation-engine中的正则表达式
  4. h3c的gpu安装linux系统,h3c服务器u盘安装linux系统安装
  5. webpack-dev-server 搭建本地服务以及浏览器实时刷新
  6. [渝粤教育] 四川大学 食物营养学 参考 资料
  7. 腾讯云函数使用方法及注意事项
  8. bp神经网络算法的优缺点,基于bp的神经网络算法
  9. 2022年天猫女王节的优惠力度比肩618年中大促购物节
  10. Mysql 入门学习总结
  11. docker 容器Exited【数字报错】问题
  12. 聚类算法K-Means K-Medoids GMM Spectral clustering,Ncut
  13. ArcGIS 中的标准分类方法
  14. RapidScada免费开源Scada组态软件系列教程5-系统进阶
  15. 辅助方法、模型、视图数据
  16. 益聚星荣:贝壳三季报曝光了二手房市场有多惨
  17. 关于如何定制开发Android第三方ROM,最全开发教程、原理阐述
  18. SQL MINUS的用法
  19. Problematic frame: C  [sigar-amd64-winnt.dll+0x14ed4]
  20. 中国方言输入法Rime入门

热门文章

  1. spring cloud组件服务架构
  2. 什么原因会导致minor gc运行频繁?
  3. Lua 脚本内部执行 Redis 命令
  4. Dubbo 融合 Nacos 成为注册中心
  5. elasticsearch集群配置文件详述
  6. python正则表达式花括号_python正则表达式(+ {})(二)
  7. ppt拖动就复制_学会这3个PPT技巧和29个快捷键!让你的PPT脱颖而出,领导叫好
  8. Qt for ios 设置程序显示名称
  9. npoi 所有列调整为一页_必能用到,一页PPT中想放超多图片怎么办?
  10. SQLSever 存储过程创建