一、定义与特点
原型模式(Prototype Pattern)是用于创建重复的对象,同时又能保证性能。这种类型的设计模式属于创建型模式,它提供了一种创建对象的最佳方式。
这种模式是实现了一个原型接口,该接口用于创建当前对象的克隆。当直接创建对象的代价比较大时,则采用这种模式。例如,一个对象需要在一个高代价的数据库操作之后被创建。我们可以缓存该对象,在下一个请求时返回它的克隆,在需要的时候更新数据库,以此来减少数据库调用。文章源自新逸网络-https://www.xinac.net/8875.html
- 原型模式通常适用于以下场景
1、对象之间相同或相似,即只是个别的几个属性不同的时候。
2、对象的创建过程比较麻烦,但复制比较简单的时候。
3、资源优化、性能和安全要求的场景。
4、类初始化需要消化非常多的资源,这个资源包括数据、硬件资源等。
5、产生一个对象需要非常繁琐的数据准备或访问权限。
6、一个对象多个修改者的场景。
7、一个对象需要提供给其他对象访问,而且各个调用者可能都需要修改其值时。
二、实现方式
(1)创建抽象类
创建一个抽象类,实现Cloneable
接口。文章源自新逸网络-https://www.xinac.net/8875.html
/**
* 形状抽象类
*/
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;
}
}
(2)创建实体类
创建实体类,继承抽象类,并实现其抽象方法。文章源自新逸网络-https://www.xinac.net/8875.html
/**
* 方形
*/
public class Rectangle extends Shape {
public Rectangle() {
super("This is a Rectangle.");
}
@Override
void draw() {
System.out.println("Rectangle::draw()");
}
}
创建实体类,继承抽象类,并实现其抽象方法。文章源自新逸网络-https://www.xinac.net/8875.html
/**
* 圆形
*/
public class Circle extends Shape {
public Circle() {
super("This is a Circle.");
}
@Override
void draw() {
System.out.println("Circle::draw()");
}
}
(3)模拟原型模式
模拟从数据库中加载数据并缓存,当需要获取类的实例时,返回clone的实例。文章源自新逸网络-https://www.xinac.net/8875.html
/**
* 创建类,模拟从数据库获取实体类数据,并缓存
*/
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);
}
}
(4)测试原型模式实现
测试实现文章源自新逸网络-https://www.xinac.net/8875.html
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));
}
}
测试输出内容文章源自新逸网络-https://www.xinac.net/8875.html
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
文章源自新逸网络-https://www.xinac.net/8875.html 文章源自新逸网络-https://www.xinac.net/8875.html
新逸IT技术
扫一扫关注微信公众号
评论