原型 (Prototype)
原型 (Prototype) 是一种创建型设计模式,它允许你复制现有对象,而不使你的代码依赖于它们的具体类。通过“克隆”得到新实例,避免重复执行昂贵的初始化或从外部资源加载的逻辑。
- 需要创建与已有对象状态相同或相近的对象,且不希望依赖该对象所属类的构造方式。
- 对象创建成本高(如复杂计算、IO、网络),复制已有实例比重新构建更合适。
- 希望客户端与具体产品类解耦,只依赖“可克隆”的抽象接口。
- 定义原型接口(如
Cloneable或自定义Prototype),声明克隆方法(如clone())。 - 具体原型类实现该接口,在克隆方法中复制自身(浅拷贝或深拷贝,按需选择)。
- 客户端通过已有实例调用
clone()得到新对象,无需知道具体类名或构造参数。
classDiagram
class Prototype {
<<interface>>
+clone()* Prototype
}
class ConcretePrototypeA {
-field String
+clone() Prototype
}
class ConcretePrototypeB {
-state int
+clone() Prototype
}
class Client {
+operation(Prototype p) void
}
Prototype <|.. ConcretePrototypeA
Prototype <|.. ConcretePrototypeB
Client ..> Prototype : uses
Java 示例
Section titled “Java 示例”方式一:实现 Cloneable 与重写 clone()(浅拷贝):
public class Document implements Cloneable { private String title; private String content;
public Document(String title, String content) { this.title = title; this.content = content; }
@Override public Document clone() { try { return (Document) super.clone(); } catch (CloneNotSupportedException e) { throw new AssertionError(e); } }
public void setTitle(String title) { this.title = title; } public void setContent(String content) { this.content = content; }}方式二:自定义原型接口 + 深拷贝:
public interface Prototype<T> { T clone();}
public class Config implements Prototype<Config> { private String env; private List<String> hosts; // 引用类型,深拷贝需单独复制
public Config(String env, List<String> hosts) { this.env = env; this.hosts = new ArrayList<>(hosts); }
@Override public Config clone() { return new Config(this.env, new ArrayList<>(this.hosts)); }}客户端使用:
public class Client { public static void main(String[] args) { Document original = new Document("报告", "内容..."); Document copy = original.clone(); copy.setTitle("报告-副本"); // original 与 copy 相互独立 }}浅拷贝与深拷贝
Section titled “浅拷贝与深拷贝”- 浅拷贝:只复制对象本身及其值类型字段;引用类型字段仍指向原对象内部引用,修改会影响原对象。
- 深拷贝:递归复制引用类型字段指向的对象,新对象与原对象在引用结构上独立。复杂对象需根据业务决定深拷贝深度。
原型模式以“复制”替代“new + 初始化”,降低对具体类的依赖、复用已有对象状态,适合创建成本高或需要基于现有实例快速生成新实例的场景。