-
什么是原型模式
简单来讲就是根据一个原型对象复制另外一个对象,和孙悟空变身一样.
原始模型模式允许动态的增加或减少产品类,产品类不需要非得有任何事先确定的等级结构,原始模型模式适用于任何的等级结构
缺点是每一个类都必须配备一个克隆方法
在java实现原型模式主要是覆写clone
方法
举例如下:
声明一个接口,继承自Cloneable
package com.byedbl.prototype.mypackage;/*
* A Graphic Interface ( A prototype interface )
*/
import java.io.*;
public interface IGraphic extends Cloneable, Serializable {
public String getName() ;
public void setName(String gName);
}
再创建一个抽象类,里面提供一个clone方法,clone方法返回一个新的实例,这里简单的调用父类的clone方法
package com.byedbl.prototype.mypackage;/*
* An Abstract Graphic Class ( Prototype )
*/
import java.lang.*;
import java.io.*;
public abstract class Graphic implements IGraphic {
private String name;
public Object clone() {
try {
return super.clone();
} catch (CloneNotSupportedException e){
System.out.println("Do not support clone !!!");
throw new InternalError();
}
}
public String getName() {
return name;
}
public void setName(String gName) {
name = gName;
}
public abstract void doSomething();
}
再创建两个实现类
package com.byedbl.prototype.mypackage;
import com.byedbl.prototype.mypackage.Graphic;
/*
* A concrete prototype to draw a line
*/
public class LineSymbol extends Graphic {
public LineSymbol() {
}
public void doSomething() {
System.out.println("I am used to draw a line !");
}
}
package com.byedbl.prototype.mypackage;
import com.byedbl.prototype.mypackage.Graphic;
/*
* A concrete prototype to draw a note
*/
public class NoteSymbol extends Graphic {
public NoteSymbol() {
}
public void doSomething() {
System.out.println("I am used to draw a note !");
}
}
缓存类:
package com.byedbl.prototype;/*
* A Symbol Loader to register all prototype instance
*/
import com.byedbl.prototype.mypackage.Graphic;
import com.byedbl.prototype.mypackage.LineSymbol;
import com.byedbl.prototype.mypackage.NoteSymbol;
import java.util.*;
import java.util.concurrent.ConcurrentHashMap;
public class SymbolLoader {
private Map<String, Graphic> symbols = new ConcurrentHashMap<>();
public SymbolLoader() {
symbols.put("Line", new LineSymbol());
symbols.put("Note", new NoteSymbol());
}
public Map<String, Graphic> getSymbols() {
return symbols;
}
}
客户端测试代码
public static void main(String[] args) {
//----- Initial our prototype instance ----------
SymbolLoader myLoader = new SymbolLoader();
Map<String,Graphic> mySymbols = myLoader.getSymbols();
//----- Draw a Line -------------------------------
Graphic myLine = (Graphic)((Graphic)mySymbols.get("Line")).clone();
myLine.doSomething();
}
为什么要一个缓存类呢?因为当new一个对象很复杂,很好资源时,我们可以将已经创建好的缓存起来,这样每次用的时候只要拷贝一个就可以了.
那原型模式适合什么场景呢?
- 资源优化场景。
- 类初始化需要消化非常多的资源,这个资源包括数据、硬件资源等。
- 性能和安全要求的场景。
- 通过 new 产生一个对象需要非常繁琐的数据准备或访问权限,则可以使用原型模式。 5. 一个对象多个修改者的场景。
- 一个对象需要提供给其他对象访问,而且各个调用者可能都需要修改其值时,可以考虑使用原型模式拷贝多个对象供调用者使用。
- 在实际项目中,原型模式很少单独出现,一般是和工厂方法模式一起出现,通过 clone 的方法创建一个对象,然后由工厂方法提供给调用者
克隆应该满足的3个条件
- x.clone() != x
- x.clone().getClass() == x.getClass
- x.clone.equals(x) (非必选)
注意
复制有深复制和浅复制,浅拷贝实现 Cloneable,重写,深拷贝是通过实现 Serializable 读取二进制流。深复制要深入多少层,这是个不容易确定的问题,可能出现循环引用问题.
网友评论