原型模式用于创建重复对象,同时又能保证性能。属于创建型模式,提供了一种创建对象的最佳方式。
该模式实现了一个原型接口,接口用于创建当前对象的克隆。当直接创建对象的带价比较大时,采用这种模式。
意图:用原型实例指定创建对象的种类,并且通过拷贝这些原型创建新的对象。
解决在运行期间建立和删除原型。
何时使用:1.当一个系统应该独立于它的产品创建,构成和表示时。2. 当要实例化的类是在运行时刻指定时,例如通过动态装载。3.为了避免创建一个与掺配类层次平行的工程类层次。4. 当一个类的实例只能有几个不同状态组合中的一种时,建立相应数目的原型并且克隆他们可能比每次用合适的状态手工实例化该类更加方便一点。
关键代码:1.实现克隆操作。2.原型模式同样用于隔离类对象的使用者和具体类型(易变类)之间的耦合关系,同样要求这些易变类拥有稳定的接口。
优点:1.性能提高。2.逃避构造函数的约数。
缺点:1.配备克隆方法需要对类的功能进行通盘考虑,对于全新的类不是很难,但是对于已有的类不一定很容易,当一个类引用不支持串行化的间接对象,或者引用含有循环结构时。2. 必须实现Cloneable接口
使用场景:1. 资源优化场景 2. 类初始化需要消耗非常多的资源,资源包括数据、硬件资源等。3.性能和安全要求的场景。4.通过new产生一个对象需要非常繁琐的数据准备或者访问权限,则可以使用原型模式。5. 一个对象多个修改者的场景。6.一个对象需要提供给其他对象的访问,而且各个调用者可能都需要修改其值时,恶意考虑使用原型模式拷贝多个对象供调用者使用。7. 在实际项目中,原型模式很少单独出现,一般是和工厂方法模式一起出现,通过clone方法创建一个对象,由工厂方法提供给调用者。
代码语言:javascript复制public abstract class Shape implements Cloneable {
private String id;
protected String type;
abstract void draw();
public String getType(){
return type;
}
public String getId(){
return id;
}
public void setId(String id){
this.id=id;
}
public Object clone(){
Object clone=null;
try{
clone=super.clone();
}catch (CloneNotSupportedException e){
e.printStackTrace();
}
return clone;
}
}
代码语言:javascript复制public class Rectangle extends Shape {
public Rectangle(){
type="Rectangle";
}
@Override
public void draw(){
System.out.println("Inside Rectangle: draw() method");
}
}
代码语言:javascript复制public class Circle extends Shape {
public Circle(){
type="Circle";
}
@Override
public void draw() {
System.out.println("Inside Circle:: draw() method");
}
}
代码语言:javascript复制public class Square extends Shape {
public Square(){
type="Square";
}
@Override
public void draw(){
System.out.println("Inside Square:draw() method");
}
}
代码语言:javascript复制public class ShapeCache {
private static Hashtable<String,Shape> shapeMap=new Hashtable<>();
public static void loadCache(){
Circle circle=new Circle();
circle.setId("1");
shapeMap.put(circle.getId(),circle);
Square square=new Square();
square.setId("2");
shapeMap.put(square.getId(),square);
Rectangle rectangle=new Rectangle();
rectangle.setId("3");
shapeMap.put(rectangle.getId(),rectangle);
}
public static Shape getShape(String shapeId){
Shape cachedShape=shapeMap.get(shapeId);
return (Shape)cachedShape.clone();
}
}
参考:
菜鸟教程 原型模式