原型模式

概念:就是对对象的拷贝
浅拷贝:数据类型分为值类型(基本数据类型)和引用类型,值类型包括int、double、byte、boolean、char等简单数据类型
深拷贝:引用类型包括类、接口、数组等复杂类型。
浅克隆和深克隆的主要区别在于是否支持引用类型的成员变量的复制

java自带一种克隆模式 不过那种克隆是属于浅拷贝(实现cloneable接口)

当使用java中覆盖object中的clone方法时,其中引用对象复制的是地址(也就是说地址值和复制之前的一样,然后指向同一个对象),而不是new一个新的地址。
深拷贝的话 复制的对象是新的 复制的引用对象也是新的。
**在Java语言中,如果需要实现深克隆,可以通过序列化(Serialization)等方式来实现。**序列化就是将对象写到流的过程,写到流中的对象是原有对象的一个拷贝,而原对象仍然存在于内存中。通过序列化实现的拷贝不仅可以复制对象本身,而且可以复制其引用的成员对象,因此通过序列化将对象写到一个流中,再从流里将其读出来,可以实现深克隆。需要注意的是能够实现序列化的对象其类必须实现Serializable接口,否则无法实现序列化操作。下面我们使用深克隆技术来实现工作周报和附件对象的复制,由于要将附件对象和工作周报对象都写入流中,因此两个类均需要实现Serializable接口
修改后的附件类Attachment代码如下:

import  java.io.*;
//附件类
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);
     }
}
 工作周报类WeeklyLog不再使用Java自带的克隆机制,而是通过序列化来从头实现对象的深克隆,我们需要重新编写clone()方法,修改后的代码如下:
import  java.io.*;
//工作周报类
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();
       }
}
      客户端代码如下所示:
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
   从输出结果可以看出,由于使用了深克隆技术,附件对象也得以复制,因此用“==”比较原型对象的附件和克隆对象的附件时输出结果均为false。深克隆技术实现了原型对象和克隆对象的完全独立,对任意克隆对象的修改都不会给其他对象产生影响,是一种更为理想的克隆实现方式。

原型管理器
关键在于管理器中创建一个 hashmap来存储复制的对象 且改为单例模式
原型管理器(Prototype Manager)是将多个原型对象存储在一个集合中供客户端使用,它是一个专门负责克隆对象的工厂,其中定义了一个集合用于存储原型对象,如果需要某个原型对象的一个克隆,可以通过复制集合中对应的原型对象来获得。在原型管理器中针对抽象原型类进行编程,以便扩展。
在这里插入图片描述

import java.util.*;
//抽象公文接口,也可定义为抽象类,提供clone()方法的实现,将业务方法声明为抽象方法
interface OfficialDocument extends  Cloneable
{
       public  OfficialDocument clone();
       public  void display();
}
 
//可行性分析报告(Feasibility Analysis Report)类
class FAR implements OfficialDocument
{
       public  OfficialDocument clone()
      {
              OfficialDocument  far = null;
              try
              {
                     far  = (OfficialDocument)super.clone();
              }
              catch(CloneNotSupportedException  e)
              {
                      System.out.println("不支持复制!");
              }
             return  far;
       }  
       public  void display()
       {
              System.out.println("《可行性分析报告》");
       }
} 
//软件需求规格说明书(Software Requirements Specification)类
class SRS implements OfficialDocument
{
       public  OfficialDocument clone()
       {
              OfficialDocument  srs = null;
              try
              {
                     srs  = (OfficialDocument)super.clone();
              }
              catch(CloneNotSupportedException  e)
              { 
                     System.out.println("不支持复制!");
              }
              return  srs;
       }      
       public  void display()
       {
              System.out.println("《软件需求规格说明书》");
       }
} 
//原型管理器(使用饿汉式单例实现)
class  PrototypeManager
{
       //定义一个Hashtable,用于存储原型对象
       private Hashtable ht=new Hashtable();
       private static PrototypeManager pm =  new PrototypeManager();    
       //为Hashtable增加公文对象   
     private  PrototypeManager()
     {
              ht.put("far",new  FAR());
              ht.put("srs",new  SRS());               
     } 
     //增加新的公文对象
       public void addOfficialDocument(String  key,OfficialDocument doc)
       {
              ht.put(key,doc);
       } 
       //通过浅克隆获取新的公文对象
       public OfficialDocument  getOfficialDocument(String key)
       {
              return  ((OfficialDocument)ht.get(key)).clone();
       }     
       public static PrototypeManager  getPrototypeManager()
       {
              return pm;
       }
}
      客户端代码如下所示:
class Client
{
       public  static void main(String args[])
       {
              //获取原型管理器对象
              PrototypeManager pm =  PrototypeManager.getPrototypeManager(); 
              OfficialDocument  doc1,doc2,doc3,doc4;
         
              doc1  = pm.getOfficialDocument("far");
              doc1.display();
              doc2  = pm.getOfficialDocument("far");
              doc2.display();
              System.out.println(doc1  == doc2);
           
              doc3  = pm.getOfficialDocument("srs");
              doc3.display();
              doc4  = pm.getOfficialDocument("srs");
              doc4.display();
              System.out.println(doc3  == doc4);
       }
}
      编译并运行程序,输出结果如下:
	《可行性分析报告》
	《可行性分析报告》
	false
	《软件需求规格说明书》
	《软件需求规格说明书》
	false

在这里插入图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值