您的位置:首页 > 其它

设计模式学习笔记(原型模式)

2011-11-23 20:28 239 查看
转载自:http://www.impeng.org/prototype.html

原型模式(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,将对象写入内存,然后再从内存读取(反序列化)。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: