原型模式的核心思想
原型模式的核心是使用一个原型接口来定义一个克隆方法,该方法允许对象自身进行复制。通过这个克隆方法,可以快速生成一个与原型对象相同的实例,而不需要直接创建新对象并手动设置属性。
原型模式的结构
原型接口(Prototype):定义一个 clone() 方法,用于克隆对象。
具体原型类(Concrete Prototype):实现原型接口,提供自身的复制方法。
客户端(Client):通过调用原型对象的 clone() 方法来创建新的对象,而不是通过构造函数。
原型模式的实现
示例:假设我们有一个 Shape 类,使用原型模式来克隆不同类型的形状对象。
import java.util.HashMap;
import java.util.Map;
// 原型接口
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;
}
// 实现克隆方法
@Override
public Object clone() {
Object clone = null;
try {
clone = super.clone();
} catch (CloneNotSupportedException e) {
e.printStackTrace();
}
return clone;
}
}
// 具体原型类:Rectangle
class Rectangle extends Shape {
public Rectangle() {
type = "Rectangle";
}
@Override
public void draw() {
System.out.println("Drawing a Rectangle");
}
}
// 具体原型类:Circle
class Circle extends Shape {
public Circle() {
type = "Circle";
}
@Override
public void draw() {
System.out.println("Drawing a Circle");
}
}
// 具体原型类:Square
class Square extends Shape {
public Square() {
type = "Square";
}
@Override
public void draw() {
System.out.println("Drawing a Square");
}
}
// ShapeCache 用于缓存形状对象并克隆
class ShapeCache {
private static Map<String, Shape> shapeMap = new HashMap<>();
// 获取缓存的形状的克隆对象
public static Shape getShape(String shapeId) {
Shape cachedShape = shapeMap.get(shapeId);
return (Shape) cachedShape.clone();
}
// 模拟加载形状对象到缓存
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 class Main {
public static void main(String[] args) {
// 预加载缓存中的形状对象
ShapeCache.loadCache();
// 通过克隆获取对象
Shape clonedShape1 = ShapeCache.getShape("1");
System.out.println("Shape : " + clonedShape1.getType()); // 输出 "Shape : Circle"
Shape clonedShape2 = ShapeCache.getShape("2");
System.out.println("Shape : " + clonedShape2.getType()); // 输出 "Shape : Square"
Shape clonedShape3 = ShapeCache.getShape("3");
System.out.println("Shape : " + clonedShape3.getType()); // 输出 "Shape : Rectangle"
}
}
原型模式的要点
克隆方法:在 Shape 类中,clone() 方法来自 Cloneable 接口,允许创建当前对象的副本。
缓存原型对象:ShapeCache 类缓存了各种形状对象,并通过 getShape() 方法来克隆它们,客户端可以从缓存中获取新对象,而无需重新创建。
对象的浅拷贝和深拷贝:clone() 方法默认进行的是浅拷贝,如果对象包含引用类型的成员变量,可能需要进行深拷贝。
浅拷贝与深拷贝
浅拷贝:只复制对象的基本类型字段和对象引用,引用类型的字段指向的是同一个对象(即对象内引用的对象未被复制)。
深拷贝:不仅复制对象本身,还递归复制对象所引用的所有对象。深拷贝可以通过手动实现,或者使用序列化的方式来完成。
原型模式在现实中的应用
对象池:比如在数据库连接池中,可以通过克隆原型连接来快速创建新的数据库连接对象。
游戏开发:在游戏中,常常需要创建相似的对象(如游戏角色、道具等),原型模式可以用来快速复制对象并应用不同的属性。
文档编辑软件:可以将常用的模板文档作为原型,快速生成新的文档副本。
通过使用原型模式,Java开发者可以有效提高对象创建的效率,减少资源消耗,并且方便地管理对象的复制和创建过程。