说明
作用:用于创建重复的对象,同时又能保证性能。属于创建型模式。
意图:用原型实例指定创建对象的种类,并通过拷贝来创建新对象。
原型模式包含如下角色:
- 抽象原型类:规定了具体原型对象必须实现的的
clone()
方法。 - 具体原型类:实现抽象原型类的
clone()
方法,它是可被复制的对象。 - 访问类:使用具体原型类中的
clone()
方法来复制新的对象。
抽象原型类:实现Cloneable
接口
public abstract class Shape implements Cloneable{
private Integer id;
private String type;
abstract void draw();
@Override
protected Object clone() throws CloneNotSupportedException {
Object clone = null;
try {
clone = super.clone();
} catch (CloneNotSupportedException e) {
e.printStackTrace();
}
return clone;
}
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;
}
}
实现类
public class Circle extends Shape{
public Circle() {
super.setType("Circle");
}
@Override
void draw() {
System.out.println("Circle...");
}
}
public class Rectangle extends Shape{
public Rectangle() {
super.setType("Rectangle");
}
@Override
public void draw() {
System.out.println("Rectangle.....");
}
}
public class Square extends Shape{
public Square() {
super.setType("Square");
}
@Override
void draw() {
System.out.println("Square...");
}
}
访问类:使用map
进行保存,需要提前将所有类型初始化在map
中
public class ShapeCache {
private static Map<String, Shape> shapeMap = new HashMap();
public static Shape getShape(String id) {
Shape shape = shapeMap.get(id);
return (Shape) shape.clone();
}
// 初始化
static {
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 class PrototypePatternDemo {
public static void main(String[] args) {
Shape clonedShape = ShapeCache.getShape("1");
System.out.println("Shape : " + clonedShape.getType());
Shape clonedShape2 = ShapeCache.getShape("2");
System.out.println("Shape : " + clonedShape2.getType());
Shape clonedShape3 = ShapeCache.getShape("3");
System.out.println("Shape : " + clonedShape3.getType());
}
}
使用场景
- 类初始化需要消化非常多的资源,这个资源包括数据、硬件资源等,通过原型拷贝避免这些消耗。
- 通过
new
一个对象需要非常繁琐的数据准备或访问权限,可以使用原型模式。 - 一个对象需要提供给其他对象访问,而且各个调用者可能需要修改其值,可以考虑使用原型模式拷贝多个对象供调用者使用,即保护性拷贝。
案例来源菜鸟教程。