`
aniu2008
  • 浏览: 42679 次
  • 性别: Icon_minigender_1
  • 来自: 北京
社区版块
存档分类
最新评论

原型模式的Java实现

阅读更多

(Prototype)原型模式的Java实现 2010-06-16 08:34:01

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

分享到:
评论

相关推荐

    常用设计模式java实现

    设计模式是软件工程中经过长期实践总结出的通用解决方案,它们描述了在特定情况下如何解决...通过阅读和学习提供的"常用设计模式java实现"压缩包中的例子,可以更好地理解和实践这些设计模式,从而提升Java编程技能。

    设计模式Java实现

    "设计模式Java实现"是一个专注于将这些模式应用到Java语言中的资源。这个压缩包可能包含了各种设计模式的Java源代码示例,帮助开发者理解和掌握如何在实际项目中应用这些模式。 1. **工厂模式**: 工厂模式是一种...

    设计模式之原型模式Java实现和类设计图

    ### 二、Java实现原型模式 在Java中实现原型模式,首先需要让原型类实现`Cloneable`接口,并重写`clone()`方法。以下是一个简单的示例: ```java public class Prototype implements Cloneable { private String ...

    设计模式java实现代码

    在这个"设计模式java实现代码"的压缩包中,我们可以期待找到各种设计模式的Java代码示例。 1. **单例模式**(Singleton):确保一个类只有一个实例,并提供一个全局访问点。在Java中,通常使用双重检查锁定(Double...

    23三种设计模式java实现

    下面将详细介绍这三类设计模式以及它们在Java中的实现。 1. **创建型设计模式** - **单例模式**:确保一个类只有一个实例,并提供全局访问点。在Java中,可以通过双重检查锁定(Double-Checked Locking)或者静态...

    23种设计模式java实现

    "23种设计模式java实现"这个压缩包包含的资源,正是针对这23种经典设计模式提供了Java代码实现,旨在帮助初学者更好地理解和应用这些模式。 1. **单例模式(Singleton)**:确保一个类只有一个实例,并提供一个全局...

    java常用23中设计模式

    总体来说设计模式分为三大类: 创建型模式,共五种:工厂方法模式、抽象工厂模式、单例模式、建造者模式、原型模式。 结构型模式,共七种:适配器模式、装饰器模式、代理模式、外观模式、桥接模式、组合模式、享元...

    读书笔记:软件设计原则与设计模式 Java实现.zip

    读书笔记:软件设计原则与设计模式 Java实现

    【资源免费下载】Java代码积累丨大话设计模式(Java实现版本)、线程协作

    Java代码积累:并发 设计模式 数据结构 使用容器 实用 类 基础知识 并发性 演示线程的生命周期 生产者-消费者 设计模式参考《大话设计模式》 工厂简单模式 创造型模式 工厂方法模式 抽象工厂模式 原型模式 建造者...

    读书笔记:Java代码积累 大话设计模式Java实现版本、线程协作.zip

    读书笔记:Java代码积累 大话设计模式Java实现版本、线程协作

    二十三种设计模式JAVA实现源码.zip

    设计模式是软件工程中的一种最佳...这些设计模式的Java实现源码,可以帮助开发者深入理解每种模式的原理和应用场景,提高代码质量和可维护性。通过阅读和实践,可以提升软件设计能力,为复杂项目的开发奠定坚实基础。

    读书笔记:23种设计模式Java实现依托于&lt;&lt;大话设计模式&gt;&gt;这本书.zip

    读书笔记:23种设计模式Java实现依托于&lt;&lt;大话设计模式&gt;&gt;这本书

    设计模式Java版各个实现代码

    本资料集“设计模式Java版”包含了各种设计模式的实现代码,旨在帮助学习者深入理解和应用这些模式。 1. **单例模式**:确保一个类只有一个实例,并提供全局访问点。在Java中,单例模式可以通过懒汉式(线程不安全...

    23种设计模式java实现源码byhrh

    用java实现了全部23种设计模式,代码简单易懂,注释详细,仅作学习使用——hrh。

    23种设计模式的Java实现

    设计模式是软件工程中经过长期实践总结出的通用解决方案,它们是...以上23种设计模式在Java实现中,通常涉及面向对象的特性,如继承、多态、封装等。理解并熟练应用这些模式,有助于编写出更加灵活、易于维护的代码。

    java版本的设计模式的实现demo

    以下是关于Java版本设计模式实现demo的一些补充说明: 1. 设计模式分类 设计模式通常分为三大类:创建型模式、结构型模式和行为型模式。创建型模式关注对象的创建;结构型模式关注类或对象的组合;行为型模式则关注类或...

    一个有趣的有限状态机的JAVA实现

    在IT领域,有限状态机(Finite State Machine, FSM)是一种重要的设计模式,它在软件工程、计算机科学以及许多其他领域都有广泛的应用。本主题“一个有趣的有限状态机的JAVA实现”将带你探索如何利用Java语言构建一...

    Java实现工厂设计模式

    Java实现工厂设计模式 Java 实现工厂设计模式是软件设计模式中的一种,属于创建型模式。工厂模式提供了一种创建对象的方式,能够将对象的创建和使用分离,使得系统更加灵活和可扩展。 在 Java 中,工厂模式通常...

    23种设计模式的实现(Java 版),java设计模式

    2. **原型模式**:同样属于创建型设计模式,原型模式允许我们通过复制现有对象来创建新对象,而不是通过创建新实例。这在对象创建成本较高或需要复杂初始化时非常有用。 3. **建造者模式**:建造者模式是一种创建型...

Global site tag (gtag.js) - Google Analytics