原型(Prototype)模式:将一个对象作为原型,通过对其进行复制而克隆出多个和原型类似的新实例。
原型模式(Prototype Pattern)是用于创建重复的对象,同时又能保证性能。这种类型的设计模式属于创建型模式,它提供了一种创建对象的最佳方式。
这种模式是实现了一个原型接口,该接口用于创建当前对象的克隆。当直接创建对象的代价比较大时,则采用这种模式。例如,一个对象需要在一个高代价的数据库操作之后被创建。我们可以缓存该对象,在下一个请求时返回它的克隆,在需要的时候更新数据库,以此来减少数据库调用。
创建一个抽象类,实现Cloneable
接口。
/**
* 形状抽象类
*/
public abstract class Shape implements Cloneable {
public Shape(String type) {
this.type = type;
}
private Integer id;
// 类型
protected String type;
// 绘制图制
abstract void draw();
public Integer getId() {
return id;
}
public void setId(Integer id) {
this.id = id;
}
public String getType() {
return type;
}
public void setType(String type) {
this.type = type;
}
@Override
public Object clone() {
Object object = null;
try {
object = super.clone();
} catch (CloneNotSupportedException e) {
e.printStackTrace();
}
return object;
}
}
创建实体类,继承抽象类,并实现其抽象方法。
/**
* 方形
*/
public class Rectangle extends Shape {
public Rectangle() {
super("This is a Rectangle.");
}
@Override
void draw() {
System.out.println("Rectangle::draw()");
}
}
创建实体类,继承抽象类,并实现其抽象方法。
/**
* 圆形
*/
public class Circle extends Shape {
public Circle() {
super("This is a Circle.");
}
@Override
void draw() {
System.out.println("Circle::draw()");
}
}
模拟从数据库中加载数据并缓存,当需要获取类的实例时,返回clone的实例。
/**
* 创建类,模拟从数据库获取实体类数据,并缓存
*/
public class ShapeCache {
private static Hashtable<Integer, Shape> shapeMap = new Hashtable<Integer, Shape>();
public static Shape getShape(Integer id) {
Shape cachedShape = shapeMap.get(id);
return (Shape) cachedShape.clone();
}
public static Shape getShapeOri(Integer id) {
Shape cachedShape = shapeMap.get(id);
return (Shape) cachedShape;
}
/**
* 模拟对数据库的查询,创建类的实例
*/
public static void loadCache() {
Circle circle = new Circle();
circle.setId(1);
shapeMap.put(circle.getId(), circle);
Rectangle rectangle = new Rectangle();
rectangle.setId(2);
shapeMap.put(rectangle.getId(), rectangle);
}
}
测试实现
public class Test {
public static void main(String[] args) {
// 初始化加载实例对象
ShapeCache.loadCache();
// 获取实例1
Shape shape1 = ShapeCache.getShape(1);
System.out.println(shape1.getType());
// clone实例比较
System.out.println(ShapeCache.getShape(1) == ShapeCache.getShape(1));
// 原始实例比较
System.out.println(ShapeCache.getShapeOri(1) == ShapeCache.getShapeOri(1));
System.out.println();
// 获取实例2
Shape shape2 = ShapeCache.getShape(2);
System.out.println(shape2.getType());
// clone实例比较
System.out.println(ShapeCache.getShape(2) == ShapeCache.getShape(2));
// 原始实例比较
System.out.println(ShapeCache.getShapeOri(2) == ShapeCache.getShapeOri(2));
}
}
测试输出内容
This is a Circle.
false
true
This is a Rectangle.
false
true
注意事项
与通过对一个类进行实例化来构造新对象不同的是,原型模式是通过拷贝一个现有对象生成新对象的。浅拷贝实现Cloneable
,重写,深拷贝是通过实现Serializable
读取二进制流。
优缺点
1、性能提高。
2、逃避构造函数的约束。
3、必须实现Cloneable
接口。
模式结构
1、抽象原型类:规定了具体原型对象必须实现的接口。
2、具体原型类:实现抽象原型类的clone()
方法,它是可被复制的对象。
3、访问类:使用具体原型类中的clone()
方法来复制新的对象。
参考文章
1、http://c.biancheng.net/view/1343.html
2、https://www.runoob.com/design-pattern/prototype-pattern.html
本文由 新逸Cary 创作,如果您觉得本文不错,请随意赞赏
采用 知识共享署名4.0 国际许可协议进行许可
本站文章除注明转载/出处外,均为本站原创或翻译,转载前请务必署名
原文链接:https://blog.xinac.cn/archives/java-design-prototype.html
最后更新:2020-08-12 14:26:31
Update your browser to view this website correctly. Update my browser now