原型模式
有的时候,我们需要一个实例时,并且,当创建一个实例的过程比较复杂或者说是昂贵时,
比如,创建实例的构造函数非常的复杂,在执行这个构造函数时会消耗较长的时间,
同时呢,这个构造函数中的一些信息又没有什么变化
(也就是说创建第一个实例时初始化信息是这样的,创建第二个实例时初始化信息还是还是这样的),
那么直接使用 new 来创建这样一个实例就显得太昂贵了,
最好的解决方法,并不是使用 new 来实例化一个对象,
而是使用克隆,也就是复制,克隆呢,就是通过复制现在已经有了的实例来创建新的实例,
这样有什么好处呢?
很明显,这样实现呢,客户端根本就不知道具体要实例化的是哪一个类,
它只知道是复制了,但具体的实例化情况,它却是一无所知的,这样便对客户端进行了隐藏,
同时,复制一个对象一般情况下会比创建一个对象性能更高(当然有时候也不一定,只是一般情况而已),
其实上面所提到的就是下面要介绍的一个设计模式--原型模式(Prototype),
原型模式(Prototype)
定义:用原型实例指定创建对象的种类,并且通过拷贝这些原型来创建新的实例。
换句话说,原型模式就是通过复制现在已经存在的对象来创建一个新的对象。
原型模式的结构类图如下:
从上面这副类图中,可以看出,在 AbstractPrototype 中只声明了一个方法,那就是克隆自身。要理解原型原型模式必须先理解Java里的浅复制和深复制。有的地方,复制也叫做克隆。Java提供这两种克隆方式。
浅克隆:被克隆对象的所有变量都含有与原来的对象相同的值,而它所有的对其他对象的引用都仍然指向原来的对象。换一种说法就是浅克隆仅仅克隆所考虑的对象,而不克隆它所引用的对象。
深克隆:被克隆对象的所有变量都含有与原来的对象相同的值,但它所有的对其他对象的引用不再是原有的,而这是指向被复制过的新对象。换言之,深复制把要复制的对象的所有引用的对象都复制了一遍,这种叫做间接复制。深复制的源代码如下:
- public Object deepClone() throws IOException, OptionalDataException, ClassNotFoundException
- {
- //write to stream
- ByteArrayOutputStream bo = new ByteArrayOutputStream();
- ObjectOutputStream oo = new ObjectOutputStream(bo);
- oo.writeObject(this); //read from stream ByteArrayInputStream bi = new ByteArrayInputStream(bo.toByteArray());
- ObjectInputStream oi = new ObjectInputStream(bi);
- return (oi.readObject());
- }
Java语言的构建模型直接支持原型模型模式,所有要克隆的类必须实现一个标识接口Cloneable。所有的类都有一个Clone()方法(Object提供)。克隆满足的条件:对于任何对象x,都有 x.clone()!=x,换言之,克隆的对象不是原来的对象;x.clone().getClass()==x.getClass(),换言之,克隆的对象与原对象是同一类型。x.clone().equals(x)成立。
- public class Sheep implements Cloneable
- {
- private String name = "Dolly";
- public Object clone() throws CloneNotSupportedException
- {
- return super.clone();
- }
- }
原型模式定义: 用原型实例指定创建对象的种类,并且通过拷贝这些原型创建新的对象.
Prototype模式允许一个对象再创建另外一个可定制的对象,根本无需知道任何如何创建的细节,工作原理是:通过将一个原型对象传给那个要发动创建的对象,这个要发动创建的对象通过请求原型对象拷贝它们自己来实施创建。
如何使用? 因为Java中的提供clone()方法来实现对象的克隆,所以Prototype模式实现一下子变得很简单.
以勺子为例:
- public abstract class AbstractSpoon implements Cloneable
- {
- String spoonName;
- public void setSpoonName(String spoonName) {this.spoonName = spoonName;}
- public String getSpoonName() {return this.spoonName;}
- public Object clone()
- {
- Object object = null;
- try {
- object = super.clone();
- } catch (CloneNotSupportedException exception) {
- System.err.println("AbstractSpoon is not Cloneable");
- }
- return object;
- }
- }
- 有个具体实现(ConcretePrototype):
- public class SoupSpoon extends AbstractSpoon
- {
- public SoupSpoon()
- {
- setSpoonName("Soup Spoon");
- }
- }
调用Prototype模式很简单:
AbstractSpoon spoon = new SoupSpoon();
AbstractSpoon spoon2 = spoon.clone();
当然也可以结合工厂模式来创建AbstractSpoon实例。
在Java中Prototype模式变成clone()方法的使用,由于Java的纯洁的面向对象特性,使得在Java中使用设计模式变得很自然,两者已经几乎是浑然一体了。这反映在很多模式上,如Interator遍历模式。
浙公网安备 33010602011771号