原型模式:
原型模式(Prototype Pattern)是一种创建型设计模式,它提供了一种创建新对象的机制,通过复制已有对象来创建具有相同或相似状态的新对象。这种模式允许我们通过克隆现有的实例来快速创建新的对象,而不是每次都通过构造函数初始化一个新的对象。
在原型模式中,主要有以下角色:
1 抽象原型(Prototype Interface):
- 这是一个接口或者抽象类,声明了克隆自身的操作(
clone()
方法)。任何需要被复制的对象都必须实现这个接口。
2 具体原型(Concrete Prototype):
- 实现了
Prototype
接口的具体类。当调用clone()
方法时,它们负责创建自己的一个副本。
3 客户端(Client):
- 客户端不直接创建新的对象,而是请求原型实例进行复制操作。它可以请求任意类型的原型实例,并且无需知道具体的创建细节。
示例代码:
java 示例代码
java
// 抽象原型接口
interface Prototype {
Prototype clone();
}
// 具体原型类1:Shape
class Shape implements Prototype {
private String type;
public Shape(String type) {
this.type = type;
}
public String getType() {
return type;
}
// 重写clone方法以实现深拷贝(假设类型为基本类型或不可变对象,如果是复杂对象则需要处理引用)
@Override
public Prototype clone() {
try {
return (Prototype) super.clone(); // 调用Object的clone方法
} catch (CloneNotSupportedException e) {
throw new RuntimeException("Cloning is not supported", e);
}
}
}
// 具体原型类2:Circle,继承自Shape
class Circle extends Shape {
private int radius;
public Circle(String type, int radius) {
super(type);
this.radius = radius;
}
public int getRadius() {
return radius;
}
// 重写clone方法以复制所有成员变量
@Override
public Prototype clone() {
Circle clonedCircle = (Circle) super.clone();
// 如果radius是引用类型,则需要进行深拷贝操作,这里假设它是基础类型
return clonedCircle;
}
}
// 客户端代码
public class Client {
public static void main(String[] args) {
// 创建一个原型对象
Circle circle = new Circle("Circle", 5);
// 使用原型模式克隆对象
Prototype clonedCircle = circle.clone();
System.out.println("Original Circle Type: " + circle.getType());
System.out.println("Cloned Circle Type: " + clonedCircle.getType());
// 假设已经覆盖了getRadius方法,可以访问到克隆后的对象属性
System.out.println("Original Circle Radius: " + ((Circle) circle).getRadius());
System.out.println("Cloned Circle Radius: " + ((Circle) clonedCircle).getRadius());
}
}
在Java中,为了实现原型模式,通常需要让具体原型类实现 Cloneable
接口并重写 Object
类中的 clone()
方法,以便正确实现深拷贝或浅拷贝功能。同时,还需要注意处理好引用类型成员变量的复制问题,以防止不同对象之间的引用混乱。
工作原理:
- 当客户端需要一个新对象时,它向原型请求一个克隆。
- 原型收到请求后,执行克隆操作,生成与自身状态完全相同的副本。
- 客户端得到这个克隆后的对象,可以对其进行修改,而不会影响原型对象本身。
优点:
- 提供了一个统一的接口用于创建复杂对象,隐藏了创建新对象的细节。
- 通过拷贝已有的原型对象,可以大大减少创建复杂对象所需的时间和内存消耗。
- 动态地改变对象的行为,原型模式允许我们在运行时选择要创建哪一类具体对象的副本。
使用场景:
- 当创建对象的工作(如包含大量数据初始化、资源密集型运算等)较复杂时。
- 需要避免重复初始化某些共享资源的情况。