五、原型模式
原型模式(Prototype Pattern),用于创建重复对象,并保证性能。通过实现一个原型接口,来复制创建当前对象的备份。
简介
旨在用原型实例指定创建对象的种类,并拷贝原型来创建新的对象。
应用场景:实例化类需要在运行时刻指定,或一个类的实例只有那么几种可能的状态组合中的一种时,可以用该模式。
细胞分裂、object克隆。
- 优点:性能高、避免构造函数的约束。
- 缺点:要通盘考虑需被克隆的类,一些引用、接口的设计的。需要实现Cloneable接口,逃避构造函数的约束。
一般用于资源优化、安全与性能考虑、对象实例多次修改等场景。
Java中浅拷贝是实现Cloneable接口,重写clone(),而深拷贝实现的Serializable读取二进制。
实现
创建一个抽象类Shape
和扩展的子类,定义一个ShapeCache
,该类将shape
对象存储在一个Hashtable
中,在需要时返回它的克隆。
- 创建抽象类
Shape.java
public abstarct 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(Sting id){
this.id = id;
}
public void setType(String type){
this.type = type;
}
@override
public Object clone(){
Object clone = null;
try{
clone = super.clone();
}catch(CloneNotSupportedException e){
e.printStackTrace();
}
return clone;
}
}
- 创建实现类
Rectangle.java
public class Rectangle extends Shape{
public Rectangle(){
type = "Rectangle";
}
@override
public void draw(){
System.out.print("矩形内部的 draw()方法);
}
}
Square.java
public class Square extends Shape{
public Square(){
type = "Square";
}
@override
public void draw(){
System.out.println("正方形内的 draw()方法");
}
}
Circle.java
public class Circlr extends Shape{
public Circle(){
type = "Circle"
}
@override
public void draw(){
System.out.println("圆形内的 draw()方法");
}
}
- 存储对象
创建一个类,从数据库获取实体类,并存储到Hashtable中。
ShapeCache.java
import java.util.Hashtable;
public class ShapeCache {
private static Hashtable<String,Shape> shapeMap = new Hashtable<String,Shape>();
public static Shape getShape(String shapeId){
Shape cacheShape = shapeMap.get(shapeId);
return (Shape)cacheShape.clone();
}
//对每种形状,都运行数据库查询,并创建该形状
//shapeMap.put(shapeKey,shape);
//例如需要添加三种形状
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 rect = new Rectangle();
rect.setId("3");
shapeMap.put(rect.getId(),rect);
}
}
- 演示demo
PrototypePatternDemo.java
public class PrototypePatternDemo{
public static void main(String[] args){
//加载对象到数据库(模拟),保存,以备后用
ShapeCache.loadCache();
//通过id来获取数据库中保存的实例对象的clone
Shape clonedShape1 = (Shape)ShapeCache.getShape("1");
System.out.print("获取的图形是:" + clonedShape1.getType());
Shape clonedShape2 = (Shape)ShapeCache.getShape("2");
System.out.print("获取的图形是:" + clonedShape2.getType());
Shape clonedShape3 = (Shape)ShapeCache.getShape("3");
System.out.print("获取的图形是:" + clonedShape3.getType());
}
}
- 输出结果
获取的图形是:Circle
获取的图形是:Square
获取的图形是:Rectangle