`

设计模式-原型模式(对象克隆)

阅读更多
原型模式-对象的克隆:
引用

浅克隆ShallowClone和深度克隆(DeepClone)
按照java数据类型: 基本类型(值类型)和引用类型(对象类型)
值类型包括int、double、byte、boolean、char等简单数据类型,引用类型包括类、接口、数组等复杂类型。
浅克隆值 基本类型能够进行复制,而对象引用复制的是指针。
在Java语言中,通过覆盖Object类的clone()方法可以实现浅克隆

浅克隆

//工作周报WeeklyLog
class WeeklyLog implements Cloneable
{
     //为了简化设计和实现,假设一份工作周报中只有一个附件对象,实际情况中可以包含多个附件,可以通过List等集合对象来实现
       private Attachment attachment;
private String name;
       private  String date;
       private  String content;
    public void setAttachment(Attachment  attachment) {
              this.attachment = attachment;
       }
       public  void setName(String name) {
              this.name  = name;
       }
       public  void setDate(String date) {
              this.date  = date;
       }
       public  void setContent(String content) {
              this.content  = content;
       }
public Attachment  getAttachment(){
              return (this.attachment);
       }
       public  String getName() {
              return  (this.name);
       }
       public  String getDate() {
              return  (this.date);
       }
       public  String getContent() {
              return  (this.content);
       }
     //使用clone()方法实现浅克隆
       public WeeklyLog clone()
       {
              Object obj = null;
              try
              {
                     obj = super.clone();
                     return (WeeklyLog)obj;
              }
              catch(CloneNotSupportedException  e)
              {
                     System.out.println("不支持复制!");
                     return null;
              }
       }
}

[b]客户端代码[/b]
class Client
{
       public  static void main(String args[])
       {
              WeeklyLog  log_previous, log_new;
              log_previous  = new WeeklyLog(); //创建原型对象
              Attachment  attachment = new Attachment(); //创建附件对象
              log_previous.setAttachment(attachment);  //将附件添加到周报中
              log_new  = log_previous.clone(); //调用克隆方法创建克隆对象
              //比较周报
              System.out.println("周报是否相同? " + (log_previous ==  log_new));
              //比较附件
              System.out.println("附件是否相同? " +  (log_previous.getAttachment() == log_new.getAttachment()));
       }
}
      编译并运行程序,输出结果如下:
周报是否相同?  false
附件是否相同? true



   由于使用的是浅克隆技术,因此工作周报对象复制成功,通过“==”比较原型对象和克隆对象的内存地址时输出false;但是比较附件对象的内存地址时输出true,说明它们在内存中是同一个对象。

2.深克隆
在深克隆中,无论原型对象的成员变量是值类型还是引用类型,都将复制一份给克隆对象,深克隆将原型对象的所有引用对象也复制一份给克隆对象。
   在Java语言中,如果需要实现深克隆,可以通过序列化(Serialization)等方式来实现。序列化就是将对象写到流的过程,写到流中的对象是原有对象的一个拷贝,而原对象仍然存在于内存中。通过序列化实现的拷贝不仅可以复制对象本身,而且可以复制其引用的成员对象,因此通过序列化将对象写到一个流中,再从流里将其读出来,可以实现深克隆。需要注意的是能够实现序列化的对象其类必须实现Serializable接口,否则无法实现序列化操作。
//附件类
class  Attachment implements Serializable
{
       private  String name; //附件名
       public  void setName(String name)
       {
              this.name  = name;
       }
       public  String getName()
       {
              return  this.name;
       }
     public void download()
     {
            System.out.println("下载附件,文件名为" + name);
     }
}
[b]   工作周报类WeeklyLog不再使用Java自带的克隆机制,而是通过序列化来从头实现对象的深克隆,我们需要重新编写clone()方法,修改后的代码如下:[/b]
//工作周报类
class  WeeklyLog implements Serializable
{
       private  Attachment attachment;
       private  String name;
       private  String date;
       private  String content;
       public  void setAttachment(Attachment attachment) {
              this.attachment  = attachment;
       }
       public  void setName(String name) {
              this.name  = name;
       }
       public  void setDate(String date) {
              this.date  = date;
       }
       public  void setContent(String content) {
              this.content  = content;
       }
       public  Attachment getAttachment(){
              return  (this.attachment);
       }
       public  String getName() {
              return  (this.name);
       }
       public  String getDate() {
              return  (this.date);
       }
       public  String getContent() {
              return  (this.content);
       }
   //使用序列化技术实现深克隆
       public WeeklyLog deepClone() throws  IOException, ClassNotFoundException, OptionalDataException
       {
              //将对象写入流中
              ByteArrayOutputStream bao=new  ByteArrayOutputStream();
              ObjectOutputStream oos=new  ObjectOutputStream(bao);
              oos.writeObject(this);
             
              //将对象从流中取出
              ByteArrayInputStream bis=new  ByteArrayInputStream(bao.toByteArray());
              ObjectInputStream ois=new  ObjectInputStream(bis);
              return  (WeeklyLog)ois.readObject();
       }
}
[b]深度克隆-客户端[/b]
class Client
{
       public  static void main(String args[])
       {
              WeeklyLog  log_previous, log_new = null;
              log_previous  = new WeeklyLog(); //创建原型对象
              Attachment  attachment = new Attachment(); //创建附件对象
              log_previous.setAttachment(attachment);  //将附件添加到周报中
              try
              {
                     log_new =  log_previous.deepClone(); //调用深克隆方法创建克隆对象                  
              }
              catch(Exception e)
              {
                     System.err.println("克隆失败!");
              }
              //比较周报
              System.out.println("周报是否相同? " + (log_previous ==  log_new));
              //比较附件
              System.out.println("附件是否相同? " +  (log_previous.getAttachment() == log_new.getAttachment()));
       }
}
      编译并运行程序,输出结果如下:
周报是否相同?  false
附件是否相同?  false


分享到:
评论

相关推荐

    ava常用设计模式-原型模式

    原型模式(Prototype Pattern)是一种创建型设计模式,允许通过复制现有对象来创建新对象,而不是通过实例化类来创建新对象。在需要创建大量相似对象时非常有用,它可以避免重复创建对象,从而提高性能,并且可以...

    Java设计模式-原型模式详解

    原型模式是 Java 设计模式之一,它用于创建对象时,指定创建对象的类型,并通过拷贝这些原型创建新的对象。该模式的思想就是将一个对象作为原型,对其进行复制、克隆,产生一个和原对象类似的新对象。 原型模式的...

    C++设计模式-原型模式

    原型模式(Prototype Pattern)是软件设计模式中的一种创建型模式,它提供了一种复制已有对象而不必知道其具体类别的方法。在C++中,原型模式常常利用拷贝构造函数或赋值运算符来实现对象的克隆。这种模式在需要频繁...

    24设计模式-原型模式1

    原型模式是一种设计模式,主要目的是通过复制现有对象来创建新对象,从而简化创建过程并减少对象构造的开销。在Java中,实现原型模式通常涉及`Cloneable`接口和`clone()`方法。`Cloneable`接口是一个标记接口,类...

    c++20设计模式-第4章-原型模式代码

    原型模式(Prototype Pattern)是其中一种行为设计模式,它允许我们通过复制现有对象来创建新对象,而不是通过传统方式实例化新对象。这一模式尤其适用于创建复杂或昂贵的对象,因为它提供了对象克隆的能力,从而...

    设计模式专题之(五)原型模式---设计模式原型模式示例代码(python--c++)

    原型模式是一种创建型设计模式,它提供了一种创建对象的最佳方式。在原型模式中,一个对象可以被克隆以创建新对象,而无需知道具体的创建细节。这种模式在需要重复创建相似对象时非常有用,避免了每次创建新对象时都...

    设计模式之原型模式

    总结,原型模式是一种有效且实用的设计模式,它通过克隆现有对象来创建新对象,减少了创建新对象带来的开销,特别适用于需要大量创建相似对象的场景。在实际编程中,我们可以通过合理运用原型模式,优化代码结构,...

    设计模式-实例代码

    原型模式是一种创建型设计模式,它提供了一种复制已有对象而无需再次进行繁琐初始化的过程。 在原型模式中,一个对象(原型)可以被克隆以创建与原对象具有相同属性的新对象。这种模式常用于减少创建新对象的成本,...

    设计模式的原型模式的例子

    原型模式(Prototype Pattern)是软件设计模式中的一种结构型模式,它的主要目的是通过复制已有对象来创建新对象,从而减少创建新对象的成本。在原型模式中,类的实例化过程被替换为对已有实例的克隆操作,尤其适用...

    设计模式——原型模式

    原型模式(Prototype Pattern)是一种创建型设计模式,它允许我们通过复制现有的对象来创建新对象,而无需知道具体创建过程的细节。这种模式的核心在于,它提供了一种对象克隆的简便方法,使得对象的创建过程对用户...

    iOS设计模式之原型模式

    原型模式是一种创建型设计模式,它的主要思想是通过复制已有对象来创建新对象,而不是通过构造函数来创建。这种模式适用于对象创建成本较高或者初始化过程复杂的情况,通过克隆已存在的对象,可以显著提升效率。 在...

    设计模式 -- 模仿女娲造物(入门)

    压缩包中的文件名为“ren”,这可能代表了某种与人类或者角色相关的例子,作者可能用这个例子来演示如何使用设计模式来创建和管理软件对象,如使用原型模式(Prototype)创建对象的克隆,或者使用职责链模式(Chain...

    设计模式之原型模式.docx

    【设计模式之原型模式】 设计模式是软件工程中的一种最佳实践,是对在特定上下文中反复出现的软件设计问题的解决方案。原型模式属于对象创建型模式,它的主要思想是通过复制已有对象来创建新对象,降低了类的实例化...

    设计模式课程设计---使用5个以上不同的设计模式完成(java)

    在本设计模式课程设计中,我们重点探讨了五个核心的设计模式:原型模式、单例模式、抽象工厂模式、代理模式和建造者模式。这些模式在Java编程中具有广泛的应用,能够帮助开发者创建更加灵活、可扩展和易于维护的代码...

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

    原型模式(Prototype Pattern)是其中一种行为设计模式,主要用于对象创建。它通过复制已有对象来创建新对象,而不是通过传统的构造函数来创建。在Java中,原型模式可以有效地提高性能,特别是在创建复杂对象时。 #...

    android设计模式之原型模式

    原型模式是一种创建型设计模式,它的主要思想是通过复制已有对象来创建新对象,而不是通过构造函数来创建。这种模式可以有效地减少对象创建时的开销,尤其是在需要创建大量相似对象的情况下。在Android中,原型模式...

    java设计模式【之】原型模式、深拷贝与浅拷贝【源码】【场景:克隆羊】

    java设计模式【之】原型模式、深拷贝与浅拷贝【源码】【场景:克隆羊】 * 原型模式(Prototype) * 实现方式: * 需要被克隆的 class类, 重写Object中的clone()方法,并实现Cloneable接口(否则报错 ...

    设计模式精解-GoF 23种设计模式解析附C++实现源码

    GoF(Gang of Four)所提出的23种设计模式,被认为是面向对象编程中最核心的设计原则之一。这些模式可以帮助开发者解决常见的编程问题,并提高代码的可复用性和可维护性。 #### 创建型模式 创建型模式关注的是对象...

Global site tag (gtag.js) - Google Analytics