一、概念:Prototype原型模式
:
通过复制一个或多个原型类,然后修改或填充具体的内容获得目标类的方式。
如果目标类与原型类相似或者他们本身就属于一个类型组(特别是来自一个数据集合对象),则可以使用原型模式。
二、示例
:游泳比赛选手列表小程序,先创建一个TimeSwimData类的列表的Vector对象,然后从中复制修改填充AgeSwimData类、SexSwimData类对象的Vector值,从而得到所需的不同的对象。
它的UML 类图为:
三、程序解析:
1.在程序主类SwimInfo类中声明了SwimData类,Swimmer类对象,引用了SwimData的子类
,在其构造方法中:
public SwimInfo()
{
super("Prototype example");
sdata = new TimeSwimData("d:/swimmers.txt");
setGUI();
loadswList(sdata, swList);
}
在TimeSwimmData构造方法中:
public TimeSwimData(String filename)
{
String s = "";
swimmers = new Vector();
InputFile f = new InputFile(filename);
s= f.readLine();
while (s != null) {
swimmers.addElement(new Swimmer(s));
s= f.readLine();
}
f.close();
}
2.在共同的SwimData抽象类中声明的重要的deepClone()方法
,使得子类中可以调用它得到独立的TimeSwimmData类的Vector数据。
public SwimData deepClone()
{
try {
ByteArrayOutputStream b = new ByteArrayOutputStream();
ObjectOutputStream out = new ObjectOutputStream(b);
out.writeObject(this);//对当前的对象做了流复制,使得当前的对象改变了。
ByteArrayInputStreambIn=newByteArrayInputStream(b.toByteArray());
ObjectInputStream oi = new ObjectInputStream(bIn);
return((SwimData)oi.readObject());
}
catch (Exception e) {
System.out.println("exception:"+e.getMessage());
e.printStackTrace();
return null;
}
}
3.子类中使用对得到的Vector数据做了排序(修改)得到新的Vector数据使得它的对象拥有了新的特征。
例如SexSwimData类先用构造方法获得了上述深拷贝的对象,然后用sort()方法得到了新的对象:
构造方法,其中的sd参数是TimeSwimData创建的对象:
public SexSwimData(SwimData sd) {
swimdata=sd.deepClone ();
//获得了流深拷贝后的对象。
female = true;
}
sort()方法:
public void sort() {
sexData = new Vector();
//在对象外调用,使得对象的Vector属性保持这里的改变值
for (int i=0; i<swimdata.size (); i++) {
Swimmer sw = swimdata.getSwimmer (i);
if (sw.isFemale () == female ) {
sexData.addElement (sw);
}
}
}
从而得到了基于改变原对象Vector数据的SexSwimData类对象,实现了原型模式。
扩展:
1.拷贝的形式,上述的使用ByteArrayOutputStream类的方法是对于原型类的数据比较复杂的情况下很有效的方法。当然也可以用重新声明一个数组或向量将其用原来的数据一个个的取出赋值给它,然后将其放到目标类的构造方法中实现深拷贝(这也是复制的数据成员较简单时常用的方法),如在SwimData中没有实现相应的方法,则在子类TimeSwimData类中用这样的构造方法实现对自己的拷贝,以提供给其他的子类调用它的构造方法创建独立的Vector:
public TimeSwimData(Vector sw) {
//this constructor copies vector as clone
swimmers = new Vector();
for (int i=0; i < sw.size (); i++) {
swimmers.add (sw.elementAt (i));
}
}
2.以上的生成相应的类的决策点是在用户单击相应的按钮时,决策点可以是一个类注册表或是原型管理器,管理有类似独立数据成员的子类(也可是管理多个对象组),它查看这些特征数据(可在运行时)并选择创建最合适的类,这是结合了Builder模式。
3.可以和工厂模式结合,使得每个具体类与其他的可用的具体类完全不同。
四、结论:
(1)在运行时可以根据需要,以复制的方式增加和删除类。
(2)可以基于程序条件,在运行时修改一个类的内部数据表示。
(3)可以在运行时指定新的对象,而无需创建一系列类和继承结构。
分享到:
相关推荐
IOS设计模式浅析之原型模式(Prototype)--copy - iOS知识库1
C#面向对象设计模式纵横谈(6):Prototype 原型模式(创建型模式)
设计模式之Prototype(原型) 设计模式之Builder 设计模式之Singleton(单态) 结构模式: 设计模式之Facade(外观) 设计模式之Proxy(代理) 设计模式之Adapter(适配器) 设计模式之Composite(组合) 设计模式之Decorator...
NULL 博文链接:https://hnzhoujunmei.iteye.com/blog/1032892
C#面向对象设计模式纵横谈(6):Prototype 原型模式(创建型模式) 体验课程
prototype-160-api.rar prototype-160-api.rar
Prototype-1.6.0-zh.chm 中文手册。好不容易找到的最新的prototype手册。
C#面向对象设计模式纵横谈(6):Prototype 原型模式(创建型模式) (Level 300)
Prototype模式允许一个对象再创建另外一个可定制的对象,根本无需知道任何如何创建的细节,工作原理是:通过将一个原型对象传给那个要发动创建的对象,这个要发动创建的对象通过请求原型对象拷贝它们自己来实施创建。...
- 原型模式(Prototype) - 代理模式(Proxy) - 适配器模式(Adapter) - 装饰器模式(Decorator) - 桥接模式(Bridge) - 组合模式(Composite) - 外观模式(Facade) - 享元模式(Flyweight) - 观察者模式(Observer) ...
AS-23-Shcherbakov-Prototype-Pollution-Leads-to-RCE
(二) 确保对象的唯一性——单例模式 (三) 确保对象的唯一性——单例模式 (四) 确保对象的唯一性——单例模式 (五) 原型模式-Prototype Pattern 对象的克隆——原型模式(一) 对象的克隆——原型模式(二) ...
prototype-151-api
├─第一章 旭瑶-小滴...│ 5.1-创建型设计模式-Prototype原型设计模式实战《上》.mp4 │ 5.2-创建型设计模式-Prototype原型设计模式实战《下》.mp4 │ 6.1-接口之间的桥梁-适配器设计模式你知道多少.mp4 │ 6.4
Prototype Carousel Class-图片走马灯
ember-disable-prototype-extensions-源码.rar
主要为大家详细介绍了Java设计模式之Prototype原型模式的相关资料,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
原型模式(Prototype Pattern) 2 结构型模式 这些设计模式关注类和对象的组合。继承的概念被用来组合接口和定义组合对象获得新功能的方式。 适配器模式(Adapter Pattern) 桥接模式(Bridge Pattern) 过滤器模式...
第18章 原型(prototype)模式 158 第19章 备忘录(memento)模式 163 第20章 操作型模式介绍 176 第21章 模板方法(template method)模式 182 第22章 状态(state)模式 193 第23章 策略(strategy)模式 204 第24章 命令...