2设计模式之原型模式(Prototype)
通过原型对象创建新的对象,而避免了复杂的初始化工作。
使用范围:
我们创建许多相似的对象,这些对象只是部分属性有区别,而且类的初始化工作相对复杂。
先了解三个概念:
1.copy拷贝
是简单的引用的复制。如:Object a = new Object(); Object b = a; 只是简单的将b指向与a代表对象相同的区域,a和b公用此类的对象。
2.shallow clone 浅克隆
是对引用(非基本)数据类型的拷贝。如:Object a = new Object(); Object b = a.shallowClone(); 这样的话,a指向的对象与b指向的对象不是同一个了,但是,如果Object中包含了引用类型属性,则他们的这个属性区域还是交集的,是公用的。简单的说,就是浅克隆,只能拷贝到一层。
3.deep clone 深度克隆
也叫精确克隆,如:Object a = new Object(); Object b = a.deepClone(); 这样的话,a指向的对象与b指向的对象不是同一个了, 而且,a与b的非引用属性区域也不是公用的。
在Java中,我们实现原型模式,其实就是利用其克隆机制进行编程,我们下面看看在Java中是怎样实现的吧!
克隆机制:
每个类中包含了Object.clone()方法,是protected的,我们在使用时,必须遵循下面的规则:
1.实现Cloneable接口,必须的,声明可以重写clone方法,否则抛出异常CloneNotSupported.
2.在可克隆的类中实现clone()方法,并声明为Public。
3.clone()方法中,实现精确拷贝,深度的拷贝,如果含有引用类型的数据b,则在方法内部调用b.clone()完成深度拷贝。
原型模式,其实就是创建对象时避免反复的手工初始化,使用clone方法代替。如果需要对象不同,可以在克隆函数内部加以区分,也可以在调用方手工设定。
例子程序:
例如我上传的TankWar源码中,有类,Tank,我在Tank客户端中使用了很多Tank对象,而且他们的属性大体相同,我当时没考虑使用Clone机制,就以这个为例吧!
Public Class Tank implements Cloneable {
TankClient tc = null;
Public Tank clone() {
Tank t = null;
t = (Tank)super.clone();
t.tc =(TankClient) tc.clone(); //去除浅拷贝,升级到深度拷贝
}
}
这样,当我们需要很多Tank对象时,我们可以先new一个Tank t = new Tank();
以后都是用t.clone()造Tank对象,效率会提高的。
至于使对象不同,可以在clone内部加入改动,如:
Public Tank clone() {
Tank t = null;
t = (Tank)super.clone();
T.name = autoGenerateName();
t.tc =(TankClient) tc.clone(); //去除浅拷贝,升级到深度拷贝
}
这样每个Tank就有不同的名字了。