文章目录
- 简介
- 场景
- 解决
- 示例
-
- [1. 基础抽象父类定义](#1. 基础抽象父类定义)
- [2. 矩形子类实现](#2. 矩形子类实现)
- [3. 圆形子类实现](#3. 圆形子类实现)
- [4. 客户端调用示例](#4. 客户端调用示例)
- 总结
简介
原型是一种创建型设计模式,它允许你复制现有对象,而不需要依赖它们的类。
场景
假设你有一个对象,你想创建它的一个完美副本。你会怎么做?首先,你必须创建一个相同类的新对象。然后你必须遍历原始对象的所有字段,并把它的值复制到新对象。
但是有一个问题。某些对象的字段可能是私有的,从对象本身外部不可见。
直接复制还有一个问题。你必须知道对象的类才能创建副本,因此你的代码会依赖这个类。有时你只知道对象实现的接口,但不知道具体类。
解决
原型模式把克隆过程委托给要克隆的实际对象。它为所有要克隆的对象声明一个通用接口。此接口允许你克隆对象,但不需要把代码与对象的类耦合。通常,这样的接口只包含一个clone 方法。
clone的实现在所有类中类似。它创建当前类的一个对象,并且把旧对象的所有字段值转移到新对象里。你甚至可以复制私有字段,因为大多数编程语言都允许对象访问属于同一类的其他对象的私有字段。
支持克隆的对象称为原型。
示例

1. 基础抽象父类定义
java
abstract class Shape implements Cloneable {
protected int xCoord;
protected int yCoord;
protected String fillColor;
// 基础构造方法
public Shape() {
this.xCoord = 0;
this.yCoord = 0;
this.fillColor = "#FFFFFF"; // 默认填充颜色
}
// 原型构造方法(拷贝构造核心)
protected Shape(Shape prototype) {
this.xCoord = prototype.xCoord; // 坐标克隆
this.yCoord = prototype.yCoord; // 实现位置复制
this.fillColor = prototype.fillColor; // 颜色属性继承
}
public abstract Shape clone();
}
2. 矩形子类实现
java
class Rectangle extends Shape {
private int width;
private int height;
public Rectangle(Rectangle source) {
super(source); // 调用父类拷贝构造
this.width = source.width; // 特有属性复制
this.height = source.height; // 包括宽高参数
}
@Override
public Rectangle clone() { // 返回具体子类类型
return new Rectangle(this); // 原型引导构造
}
}
3. 圆形子类实现
java
class Circle extends Shape {
private int radius;
public Circle(Circle source) {
super(source); // 父类属性初始化
this.radius = source.radius; // 半径参数拷贝
}
public void setRadius(int r) {
this.radius = r; // 半径独立可变
}
@Override
public Circle clone() {
return new Circle(this); // 生成新实例
}
}
4. 客户端调用示例
java
Shape prototype = new Circle();
prototype.setPosition(15, 20);
prototype.setColor("#FFA500");
// 快速生成克隆体
Shape clonedCircle = prototype.clone(); // 无需知道具体类型
clonedCircle.move(5, 5); // 获得独立坐标
// 构造矩形原型
Shape rectProto = new Rectangle();
rectProto.setSize(100, 200); // 原始配置
Shape clonedRect = rectProto.clone(); // 完美复制属性
总结

- 原型(Prototype)接口:声明Clone方法。在绝大多数情况下,里面只会有一个clone方法。
- 具体原型(Concrete Prototype)类:实现Clone方法。除了把原始对象的数据复制到新的克隆体中之外,这个方法有时还需处理克隆过程中的极端情况,例如克隆关联对象和递归依赖等等。
- 客户端(Client)可以复制实现了原型接口的任何对象。