分享
 
 
 

模式总结:原型模式

王朝java/jsp·作者佚名  2006-01-08
窄屏简体版  字體: |||超大  

模式的本质就是不断重复出现的问题的可重用解决方案。一个完整的模式提供使用或者不使用该解决方案的理由,使用解决方案的结果,以及怎样实现该解决方案的建议。本文中模式总结仅描述问题的本质及其解决方案。这是最后一组与创建对象相关的模式。本文将重点讲解动态决定实例化哪个类,或者一个对象把职责委托给哪些对象。这些模式会告诉我们怎样组织和封装这些决定。该文将讨论原型模式(Prototype)。通过给类指定每种将要被创建的对象的原型实例,原型模式(Prototype)使得该类可以创建那些实现已知接口的对象。

假设你正在设计一个CAD(计算机辅助设计)程序,它允许用户根据图形符号画板来作图。该程序具有一套核心的内置图形符号。但是,使用这个程序的人们往往具有不同的特殊需求。那么这套核心图形符号将不能满足人们的这种特殊需求。这些人就希望程序具有额外的图形符号来适合他们的需求。由于这个程序的大多数用户都具有特殊的需求,所以程序必须尽可能的提供额外的图形符号集,使得用户可以根据他们的需要把它们添加到程序中去。

这种需求将会引起一个问题:怎样提供那些额外图形符号的画板。你可以很容易的组织如此之多的图形符号,包括核心的和额外的,它们都继承一个共同的祖先类。这给你的作图程序使用一致的方式来操作图形符号对象提供了支持。但是它并没有解决程序怎样创建对象的问题。创建诸如此类的对象通常比简单的实例化一个类要复杂得多。它可能还包括数据属性值的设定,或结合其他对象来组成一个复合对象。

一个解决方案就是给作图程序提供预先创建好的对象,然后把它们作为创建类似对象的原型。把对象用作原型,这就要求它们具有一个方法,一般称之为clone。clone方法返回一个对象,它是原始对象的一个新的拷贝。下面的类图描述了该方案是怎样组织的:

图1 Symbol原型

作图程序维护一组用作原型的Symbol对象。通过克隆这些原型对象,作图程序可以使用Symbol对象。SymbolBuilder创建Symbol对象并且向作图程序进行注册。

所有的Java类都从Object类那里继承一个叫做clone的方法。一个对象的clone方法返回该对象的一个拷贝。clone方法只有在对象类被授权的情况下才进行拷贝。如果一个类授权给它的实例可以克隆自己,那么该类必须实现Cloneable接口。因为Symbol类实现了Cloneable接口,所以作图程序可以克隆Symbol对象。并且作图程序管理这些Symbol对象并把它们组合成图。

一般来说,通过给类指定每种将要被创建的对象的原型实例,原型模式(Prototype)使得该类可以创建那些实现已知接口的对象。因此,克隆原型实例就可以创建新对象。

下图描述了一般情况下的原型模式(Prototype)的组织结构:

图2 原型模式(Prototype)

下面描述原型模式(Prototype)中的这些类和接口所扮演的角色:

l Client

对原型模式(Prototype)的目的来说,client类表示程序的其他部分。client类需要创建它不了解的对象。Client类具有一个方法,可以调用它来给client对象的原型对象集合增加新的原型对象。在上图中,该方法的名称为registerPrototype。但是,在实际的实现中,反映被原型化的对象集合的名字被叫做为registerSymbol可能会更恰当一些。

l Prototype

扮演Prototype角色的类实现PrototypeIF接口,并且可以被client克隆而达到被实例化的目的。扮演这种角色的类通常是抽象类,且它具有许多具体的子类。

l PrototypeIF

所有的原型对象都要实现PrototypeIF接口。client类通过这个接口与原型对象进行交互。这种角色的接口应该扩展Cloneable接口,这样所有实现该接口的对象才能够被克隆。

l PrototypeBuilder

PrototypeBuilder类对应于那些被实例化以给client对象提供原型对象的任何类。像这样的类应该具有这样一个名字,它必须能够表示它所能创建的原型对象的类型,例如SymbolBuilder。PrototypeBuilder对象创建Prototype对象。它把每次新创建的Prototype对象传递给Client对象的registerPrototype方法。

该模式的示例代码是基于一个不同的情形。假设你正在编写一个交互角色的游戏比赛。也就是说,该游戏允许用户与模拟的人物角色进行交互。其中,游戏的一个需求就是玩家越来越厌烦与同一个角色进行交互,而希望与一个新角色进行交互。由于这个原因,你还需要给游戏开发一个附加部分,它由一些预先生成的角色所组成,并且需要开发一个程序来生成这些附加的角色。

游戏中的角色都是一些相关的类的实例,例如Hero,Fool,Villain和Monster。是什么使得同一个类的实例之间相互不同呢?答案就是给这些实例设置不同属性值,例如表示它们的图像,高度,宽度,智力和敏捷。

下面的类图描述了游戏中所包含的部分类:

图3 原型模式示例

清单1列出了CharacterIF接口代码,该接口扮演PrototypeIF角色。

清单1:CharacterIF接口

public interface CharacterIF extends Cloneable {

public String getName() ;

public void setName(String name) ;

public Image getImage() ;

public void setImage(Image image) ;

public int getStrength() ;

public void setStrength(int strength) ;

...

} // interface CharacterIF

下面是Character类代码,该抽象类扮演PrototypeIF角色。

清单2:Character类

public abstract class Character implements CharacterIFloneable {

...

/**

* Override clone to make it public.

*/

public Object clone() {

try {

return super.clone();

} catch (CloneNotSupportedException e) {

// This should never happen because this class implements

// Cloneable.

throw new InternalError();

} // try

} // clone()

public String getName() { return name; }

public void setName(String name) { this.name = name; }

public Image getImage() { return image; }

public void setImage(Image image) { this.image = image; }

...

} // class Character

这个类的大部分代码都是简单的存取方法。比较不清楚地方法就是clone方法。所有的对象都从Object类那里继承一个clone方法。因为这个clone方法不是公共的,所以character类必须用一个public声明来覆盖它,这只是使得它可以被其他的类访问。

清单3是Hero类的源代码,这个类所扮演的其中一个角色就是Prototype:

清单3:Hero类

public class Hero extends Character {

private int bravery;

...

public int getBravery() { return bravery; }

public void setBravery(int bravery) { this.bravery = bravery; }

} // class Hero

Monster类与Hero类相似。

下面就是CharacterManager类代码,它扮演Client角色:

清单4:CharacterManager类

public class CharacterManager {

private Vector characters = new Vector();

...

/**

* Return a copy of random character from the collection.

*/

Character getRandomCharacter() {

int i = (int)(characters.size()*Math.random());

return (Character)((Character)characters.elementAt(i)).clone();

} // getRandomCharacter()

/**

* Add a prototypical object to the collection.

*/

void addCharacter(Character character) {

characters.addElement(character);

} // addCharacter(Character)

...

} // class CharacterManager

清单5列出了CharacterLoader类的代码,它来完成PrototypeBuilder角色:

清单5:CharacterLoader类

/**

* This class loads character objects and adds them to the

* the CharacterManager.

*/

class CharacterLoader {

private CharacterManager mgr;

/**

* Constructor

* @param cm The CharacterManager that this object will work with.

*/

CharacterLoader(CharacterManager cm) {

mgr = cm;

} // Constructor(CharacterManager)

/**

* Load character objects from the specified file.

* Since failure only affects the rest of the program to the extent

* that new character objects are not loaded, we need not throw any

* exceptions.

*/

int loadCharacters(String fname) {

int objectCount = 0; // The number of objects loaded

// If construction of the InputStream fails, just return

try {

InputStream in;

in = new FileInputStream(fname);

in = new BufferedInputStream(in);

ObjectInputStream oIn = new ObjectInputStream(in);

while(true) {

Object c = oIn.readObject();

if (c instanceof Character) {

mgr.addCharacter((Character)c);

} // if

} // while

} catch (Exception e) {

} // try

return objectCount;

} // loadCharacters(String)

} // class CharacterLoader

 
 
 
免责声明:本文为网络用户发布,其观点仅代表作者个人观点,与本站无关,本站仅提供信息存储服务。文中陈述内容未经本站证实,其真实性、完整性、及时性本站不作任何保证或承诺,请读者仅作参考,并请自行核实相关内容。
2023年上半年GDP全球前十五强
 百态   2023-10-24
美众议院议长启动对拜登的弹劾调查
 百态   2023-09-13
上海、济南、武汉等多地出现不明坠落物
 探索   2023-09-06
印度或要将国名改为“巴拉特”
 百态   2023-09-06
男子为女友送行,买票不登机被捕
 百态   2023-08-20
手机地震预警功能怎么开?
 干货   2023-08-06
女子4年卖2套房花700多万做美容:不但没变美脸,面部还出现变形
 百态   2023-08-04
住户一楼被水淹 还冲来8头猪
 百态   2023-07-31
女子体内爬出大量瓜子状活虫
 百态   2023-07-25
地球连续35年收到神秘规律性信号,网友:不要回答!
 探索   2023-07-21
全球镓价格本周大涨27%
 探索   2023-07-09
钱都流向了那些不缺钱的人,苦都留给了能吃苦的人
 探索   2023-07-02
倩女手游刀客魅者强控制(强混乱强眩晕强睡眠)和对应控制抗性的关系
 百态   2020-08-20
美国5月9日最新疫情:美国确诊人数突破131万
 百态   2020-05-09
荷兰政府宣布将集体辞职
 干货   2020-04-30
倩女幽魂手游师徒任务情义春秋猜成语答案逍遥观:鹏程万里
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案神机营:射石饮羽
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案昆仑山:拔刀相助
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案天工阁:鬼斧神工
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案丝路古道:单枪匹马
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案镇郊荒野:与虎谋皮
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案镇郊荒野:李代桃僵
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案镇郊荒野:指鹿为马
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案金陵:小鸟依人
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案金陵:千金买邻
 干货   2019-11-12
 
推荐阅读
 
 
 
>>返回首頁<<
 
靜靜地坐在廢墟上,四周的荒凉一望無際,忽然覺得,淒涼也很美
© 2005- 王朝網路 版權所有