The NoteBook of EricKong

  BlogJava :: 首页 :: 联系 :: 聚合  :: 管理
  611 Posts :: 1 Stories :: 190 Comments :: 0 Trackbacks

原型模式(Prototype)属于创建型模式,实现了对象的创建;具体而言,它实现了对象的复制(拷贝)。

关于对象的复制,我们需要考虑以下两个问题:

1.对象实时状态的复制;

2.对象引用成员变量的复制。

如果通过new方式来实例化对象,只能得到对象的初始状态,这显然不行。在Java中,所有类都继承于Object类,而Object有一个clone()方法。通过查看JDK文档,该clone()方法虽然能够实现实时状态的复制(解决了问题1),但是只能实现“浅拷贝”,即只能实现基本数据类型(包含String)的拷贝,不能实现引用数据类型的拷贝,并不能满足原型模式的要求(问题2不能得到解决)。


怎么办?重写类的clone()方法,通过对象的写入写出来实现“深拷贝”和实时状态复制。重写(Override)需要遵循的条件是:方法名,参数列表和父类一致;返回值是父类返回值的子类。重写clone方法完全满足了条件。(无参数,方法名一致,返回的所有类都是Object的子类;当然可以不重写,方法名改用其它,但是不建议。)

可以想象,若一个类含有若干个引用数据类型(类),而该引用数据类型(类)中又含有若干个引用数据类型…这样嵌套下去,需要复制的就不是一个类,而是一个“类树”(树结构)。Java通过将对象序列化到文件或内存,底层封装了对类树的遍历和复制过程。这个机制已经封装,我们无需了解。

考虑这样一个应用场景:

一个RPG游戏,英雄类含有两个成员变量:一个是英雄名字,为普通成员变量;一个是英雄属性,为引用成员变量(封装了英雄的状态,如生命值、魔法值)。为了实现对象实时拷贝的高效率,我们选择将对象序列化到内存(不是文件(硬盘))。通过输入输出流实现对象的“深拷贝”。

具体的实现代码如下:


package com.csufox.Prototype;

import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;

class Property implements java.io.Serializable{
    int blood = 100;  //生命值
    int magic = 100;  //魔法值
}

class Hero implements java.io.Serializable{ //需要实现序列化接口
    String name = "英雄";
    Property property = new Property(); //含有引用成员,需要“深”拷贝

    public Hero clone(){
        Hero copy = null;
        try{
            //实例化ObjectOutputStream,写入字节数组输出流
            ByteArrayOutputStream baos = new ByteArrayOutputStream();
            ObjectOutputStream oos = new ObjectOutputStream(baos);
            oos.writeObject(this);
            byte[] data = baos.toByteArray();  //data是字节数组,存储着对象的拷贝


            //实例化ObjectInputStream,从字节数组输入流中读取对象
            ByteArrayInputStream bais = new ByteArrayInputStream(data);
            ObjectInputStream ois = new ObjectInputStream(bais);
            copy = (Hero)ois.readObject();
        }catch(Exception ex){ex.printStackTrace();}
        return copy;
    }
}

public class Prototype {
    public static void main(String[] args) throws Exception {
        Hero hero = new Hero();
        hero.property.blood -= 20;  //原英雄状态发生改变,生命值减少20
        Hero copy = hero.clone();
        System.out.println(copy.property.blood);  //输出“80”,说明实现了实时拷贝和深拷贝
    }
}
 

由上述代码可知,原型模式具有以下特点:

实现Serializable序列化接口;
在类中重写clone()方法(由Object继承而来);
通过Java I/0,将对象写入内存,然后再从内存读取(反序列化)。

posted on 2010-09-09 14:13 Eric_jiang 阅读(367) 评论(0)  编辑  收藏 所属分类: 设计模式

只有注册用户登录后才能发表评论。


网站导航: