原型模式其实就是java的拷贝机制

原文出处:http://blog.csdn.net/zhengzhb/article/details/7393528

 

定义:用原型实例指定创建对象的种类,并通过拷贝这些原型创建新的对象。

类型:创建类模式

类图:

原型模式主要用于对象的复制,它的核心是就是类图中的原型类Prototype。Prototype类需要具备以下两个条件:

  • 实现Cloneable接口。在java语言有一个Cloneable接口,它的作用只有一个,就是在运行时通知虚拟机可以安全地在实现了此接口的类上使用clone方法。在java虚拟机中,只有实现了这个接口的类才可以被拷贝,否则在运行时会抛出CloneNotSupportedException异常。
  • 重写Object类中的clone方法。Java中,所有类的父类都是Object类,Object类中有一个clone方法,作用是返回对象的一个拷贝,但是其作用域protected类型的,一般的类无法调用,因此,Prototype类需要将clone方法的作用域修改为public类型。

原型模式是一种比较简单的模式,也非常容易理解,实现一个接口,重写一个方法即完成了原型模式。在实际应用中,原型模式很少单独出现。经常与其他模式混用,他的原型类Prototype也常用抽象类来替代。

实现代码:

  1. class Prototype implements Cloneable {
  2. public Prototype clone(){
  3. Prototype prototype = null;
  4. try{
  5. prototype = (Prototype)super.clone();
  6. }catch(CloneNotSupportedException e){
  7. e.printStackTrace();
  8. }
  9. return prototype;
  10. }
  11. }
  12. class ConcretePrototype extends Prototype{
  13. public void show(){
  14. System.out.println("原型模式实现类");
  15. }
  16. }
  17. public class Client {
  18. public static void main(String[] args){
  19. ConcretePrototype cp = new ConcretePrototype();
  20. for(int i=0; i< 10; i++){
  21. ConcretePrototype clonecp = (ConcretePrototype)cp.clone();
  22. clonecp.show();
  23. }
  24. }
  25. }

原型模式的优点及适用场景

使用原型模式创建对象比直接new一个对象在性能上要好的多,因为Object类的clone方法是一个本地方法,它直接操作内存中的二进制流,特别是复制大对象时,性能的差别非常明显。

使用原型模式的另一个好处是简化对象的创建,使得创建对象就像我们在编辑文档时的复制粘贴一样简单。

因为以上优点,所以在需要重复地创建相似对象时可以考虑使用原型模式。比如需要在一个循环体内创建对象,假如对象创建过程比较复杂或者循环次数很多的话,使用原型模式不但可以简化创建过程,而且可以使系统的整体性能提高很多。

原型模式的注意事项

  • 使用原型模式复制对象不会调用类的构造方法。因为对象的复制是通过调用Object类的clone方法来完成的,它直接在内存中复制数据,因此不会调用到类的构造方法。不但构造方法中的代码不会执行,甚至连访问权限都对原型模式无效。还记得单例模式吗?单例模式中,只要将构造方法的访问权限设置为private型,就可以实现单例。但是clone方法直接无视构造方法的权限,所以,单例模式与原型模式是冲突的,在使用时要特别注意。
  • 深拷贝与浅拷贝。Object类的clone方法只会拷贝对象中的基本的数据类型,对于数组、容器对象、引用对象等都不会拷贝,这就是浅拷贝。如果要实现深拷贝,必须将原型模式中的数组、容器对象、引用对象等另行拷贝。例如:
  1. public class Prototype implements Cloneable {
  2. private ArrayList list = new ArrayList();
  3. public Prototype clone(){
  4. Prototype prototype = null;
  5. try{
  6. prototype = (Prototype)super.clone();
  7. prototype.list = (ArrayList) this.list.clone();
  8. }catch(CloneNotSupportedException e){
  9. e.printStackTrace();
  10. }
  11. return prototype;
  12. }
  13. }

由于ArrayList不是基本类型,所以成员变量list,不会被拷贝,需要我们自己实现深拷贝,幸运的是java提供的大部分的容器类都实现了Cloneable接口。所以实现深拷贝并不是特别困难。

《JAVA与模式》之原型模式(转载)的更多相关文章

  1. Java进阶篇设计模式之三 ----- 建造者模式和原型模式

    前言 在上一篇中我们学习了工厂模式,介绍了简单工厂模式.工厂方法和抽象工厂模式.本篇则介绍设计模式中属于创建型模式的建造者模式和原型模式. 建造者模式 简介 建造者模式是属于创建型模式.建造者模式使用 ...

  2. Java设计模式5:原型模式

    原型模式 原型模式属于对象的创建模式,通过给出一个原型对象来指明所有创建的对象的类型,然后用复制这个原型对象的办法创建出更多同类型的对象,这就是原型模式的用意. 原型模式结构 原型模式要求对象实现一个 ...

  3. Java设计模式之三 ----- 建造者模式和原型模式

    前言 在上一篇中我们学习了工厂模式,介绍了简单工厂模式.工厂方法和抽象工厂模式.本篇则介绍设计模式中属于创建型模式的建造者模式和原型模式. 建造者模式 简介 建造者模式是属于创建型模式.建造者模式使用 ...

  4. 【java设计模式】-06原型模式

    原型模式简述 定义: 使用原型实例指定待创建对象的类型,并且通过复制这个原型来创建新的对象 ,也就是通过复制现有对象实例产生新的对象,也就是所谓的"克隆" 实现方式: 1.实现Cl ...

  5. 《JAVA设计模式》之原型模式(Prototype)

    在阎宏博士的<JAVA与模式>一书中开头是这样描述原型(Prototype)模式的: 原型模式属于对象的创建模式.通过给出一个原型对象来指明所有创建的对象的类型,然后用复制这个原型对象的办 ...

  6. 重学 Java 设计模式:实战原型模式

    作者:小傅哥 博客:https://bugstack.cn 沉淀.分享.成长,让自己和他人都能有所收获! 一.前言 老板你加钱我的代码能飞 程序员这份工作里有两种人:一类是热爱喜欢的.一类是仅当成工作 ...

  7. 建造者模式与原型模式/builder模式与prototype模式/创建型模式

    建造者模式 定义 用于简化复杂对象的创建 JDK中的建造者模式 java.lang.StringBuilder中的append()方法,每次调用后返回修改后的对象本身. public StringBu ...

  8. 设计模式10---设计模式之原型模式(Prototype)

    1.场景模式 考虑这样一个实际应用:订单处理系统 里面有一个保存订单的功能,当产品数量超过1000份以后,拆成两份订单,再超,那么就再拆.直到每份订单不超过1000为止,订单有两种,一个是个人订单,一 ...

  9. [19/04/24-星期三] GOF23_创建型模式(建造者模式、原型模式)

    一.建造者模式 本质:分离了对象子组件的单独构造(由Builder负责)和装配的分离(由Director负责),从而可以构建出复杂的对象,这个模式适用于:某个对象的构建过程十分复杂 好处:由于构建和装 ...

  10. 初涉JavaScript模式 (7) : 原型模式 【三】

    组合使用构造函数模式和原型模式 上篇,我们提到了原型模式的缺点,就是每个实例不能拥有自己的属性,因为纯原型模式所有的属性都是公开给每个实例的,故我们可以组合使用构造函数模式和原型模式.构造函数用来定义 ...

随机推荐

  1. [Angular] Communicate with Angular Elements using Inputs and Events

    In a real world scenario we obviously need to be able to communicate with an Angular Element embedde ...

  2. Android Studio打开出现:Default activity not found

    昨天项目可以正常打开,没有问题,今天打开的时候就出现了这个问题.可以编译,但是无法生成APK调试.当然,如果选择 Do not launch Activity就可以成功编译.出现这个 Default ...

  3. C#.NET常见问题(FAQ)-如何声明list的多维数组

    可以用下面的方法来声明多维list数组,但是不推荐使用   //对于一维数组:List<数据类型> 变量 = new List<数据类型>(); List<int> ...

  4. MyCat - 使用篇

    Mycat水平拆分之十种分片规则: http://www.cnblogs.com/756623607-zhang/p/6656022.html 数据库路由中间件MyCat - 使用篇(5) 配置MyC ...

  5. 简单实用的extend对象合并

    /** * 合并对象 * 示例:o = extend({ a: 'a' }, o); */ function extend(s, t) { if (!s) { return {}; } if (!s) ...

  6. Centos7中修改Hostname的方法

    一.Centos7中修改的方法: hostnamectl set-hostname <new hostname> 说明:centOS 7 里面修改hostname的方式有所改变,修改/et ...

  7. C#实现U盘检查,并写入文件

    using System; using System.Collections.Generic; using System.ComponentModel; using System.Data; usin ...

  8. flume-elasticsearch-sink indexName

  9. Redis问题MISCONF Redis is configured to save RDB snapshots....

    Redis问题MISCONF Redis is configured to save RDB snapshots, but is currently not able to persist on di ...

  10. 软件工程各阶段的UML图

    转载请注明原文地址:http://www.cnblogs.com/ygj0930/p/6616876.html UML是统一建模语言,主要用于软件的分析与设计阶段.但是UML有这么多图,具体怎么用呢? ...