设计模式--对原型模式的思考

原型模式:

所谓的原型模式就是制造出原型对象的副本,副本对象的信息与原对象一致但是却在内存中占用不同的空间。

//下面是对原型模式应用实例:某公司需要产生许多信息大致相同的报表,但是报表少量的部分还是需要进行修改的,有需要对报表的修改不会影响到其他的报表信息。

//通用的原型设计思想

public class ReportForm implements Cloneable

{

    private String name;//报表的名称

    private String date;//报表的时间

    private String content;//报表的内容

    public ReportForm(String name, String date, Stringcontent)

    {

       super();

       this.name = name;

       this.date = date;

       this.content = content;

    }

    public String getName() {

       return name;

    }

    public void setName(String name) {

       this.name = name;

    }

    public String getDate() {

       return date;

    }

    public void setDate(String date) {

       this.date = date;

    }

    public String getContent() {

       return content;

    }

    public void setContent(String content) {

       this.content = content;

    }

    @Override

    public String toString()

    {

       return "ReportForm:"+this.hashCode()+" date="+date+"name="+name+" content="+content;

    }

    public ReportForm clone()

    {

       ReportFormform = new ReportForm(this.name,this.date, this.content);

       return form;

    }

}

//Java特有的克隆模式

public class ReportForm implements Cloneable

{

    private String name;//报表的名称

    private String date;//报表的时间

    private String content;//报表的内容

    public ReportForm(String name, String date, Stringcontent)

    {

       super();

       this.name = name;

       this.date = date;

       this.content = content;

    }

    public String getName() {

       return name;

    }

    public void setName(String name) {

       this.name = name;

    }

    public String getDate() {

       return date;

    }

    public void setDate(String date) {

       this.date = date;

    }

    public String getContent() {

       return content;

    }

    public void setContent(String content) {

       this.content = content;

    }

    @Override

    public String toString()

    {

       return "ReportForm:"+this.hashCode()+" date="+date+"name="+name+" content="+content;

    }

    public ReportForm clone()

    {

       Objectobject;

       try {

           object = super.clone();

           return(ReportForm) object;

       } catch(CloneNotSupportedException e) {

           e.printStackTrace();

           System.out.println("不能产生原型对象...");

       }

       return null;

    }

}

//客户使用原型模式:

public class Client

{

    public static void main(String[] args)

    {

       ReportForm form = new ReportForm("工作报表","第一周", "这是一份工作报表");

       ReportForm new_form = form.clone();

       new_form.setDate("第二周");

       System.out.println(form);

       System.out.println("-----------------------------------------------------------------------");

       System.out.println(new_form);

    }

}

结果(很显然客户对报表副本的修改并没有改变原型对象,那么这种设计是可行的

ReportForm:33311724 date=第一周 name=工作报表 content=这是一份工作报表

-----------------------------------------------------------------------

ReportForm:14452073 date=第二周 name=工作报表 content=这是一份工作报表

//以上通过两种方式创建原型对象的副本,但是结果都是一样的,只是创建对象的思想变了。

 

注意:此时用户的需求变了,不仅只有单纯的报表,在报表之后还需要加附件,也就是在报表类中需要加入引用类型的对象变量。

Java中引用类型的变量并不能在克隆的时候产生一个副本,那么就需要用到深拷贝技术来实现

下面是相关代码(注:java中只要被拷贝的对象都要实现Cloneable接口)

//附件类

public class Attachment implements Cloneable

{

    private String name;//附件的名称

    public Attachment(String name) {

       super();

       this.name = name;

    }

    public String getName() {

       return name;

    }

    public void setName(String name) {

       this.name = name;

    }

    public void download()

    {

       System.out.println(name+"附件被下载...");

    }

    public Attachment clone()

    {

       try {

           return(Attachment)super.clone();

       } catch(CloneNotSupportedException e) {

           e.printStackTrace();

           System.out.println("不能创建原型对象...");

           return null;

       }

    }

}

//原型类

public class ReportForm implements Cloneable

{

    private String name;//报表的名称

    private String date;//报表的时间

    private String content;//报表的内容

    private Attachment attachment;//需要被添加的附件

    public ReportForm(String name, String date, Stringcontent,

           Attachment attachment) {

       super();

       this.name = name;

       this.date = date;

       this.content = content;

       this.attachment = attachment;

    }

    public String getName() {

       return name;

    }

    public void setName(String name) {

       this.name = name;

    }

    public String getDate() {

       return date;

    }

    public void setDate(String date) {

       this.date = date;

    }

    public String getContent() {

       return content;

    }

    public void setContent(String content) {

       this.content = content;

    }

    public Attachment getAttachment() {

       return attachment;

    }

    public void setAttachment(Attachment attachment) {

       this.attachment = attachment;

    }

    @Override

    public String toString()

    {

       return "ReportForm:"+this.hashCode()+" date="+date+"name="+name+" content="+content

           +" attachment:"+attachment.hashCode()+" name="+attachment.getName();

    }

    public ReportForm clone()

    {

       ReportFormobj = null;

       try

       {

           obj =(ReportForm)super.clone();

           Attachmentobj2 = attachment.clone();

           obj.setAttachment(obj2);

       }

       catch(CloneNotSupportedException e)

       {

           e.printStackTrace();

           System.out.println("不能创建原型对像...");

       }

       return obj;

    }

}

 

结果:

ReportForm:14452073 date=第一周 name=工作报表 content=这是一份工作报表 attachment:29013258 name=附件一

-----------------------------------------------------------------------

ReportForm:12830537 date=第一周 name=工作报表 content=这是一份工作报表 attachment:22068557 name=附件一

很显然这里的附件的引用也是不一样的,实现深拷贝也成功了。

//第二种进行深拷贝的方式

就是讲要拷贝的对象写入到流中,在将流中的对象进行重构形成新的对象

public ReportForm clone()

    {

       //将该对象写入流中

       ByteArrayOutputStream bos = new ByteArrayOutputStream();

       try

       {

           ObjectOutputStream oos = new ObjectOutputStream(bos);

           oos.writeObject(this);

          

           //重构流中的对象

           ObjectInputStream ois = new ObjectInputStream(newByteArrayInputStream(bos.toByteArray()));

           ReportForm form = (ReportForm)ois.readObject();

           return form;

       }

       catch (Exceptione) {

           e.printStackTrace();

           System.out.println("不能重构对象...");

       }

      

       return null;

    }

结果:

ReportForm:20688146 date=第一周 name=工作报表 content=这是一份工作报表 attachment:23276589(打印的是该对象的hashCode) name=附件一

-----------------------------------------------------------------------

ReportForm:16602326 date=第一周 name=工作报表 content=这是一份工作报表 attachment:30191657 name=附件一

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值