5. 原型模式

原型模式

在软件设计中,我们经常需要频繁创建大量结构相同、内容类似的对象,传统方式往往通过 `new` 的方式反复构造。但是对于某些对象来说,**构建成本高、配置复杂、甚至依赖外部资源**。

这时,一个非常优雅的解决方案就是 **原型模式(Prototype Pattern)**。

一、什么是原型模式?

**原型模式(Prototype Pattern)**:

> 使用原型实例指定创建对象的种类,并通过复制这些原型创建新的对象。

也就是说,不再用 `new Xxxx()`,而是 **通过克隆(clone)直接复制已有对象**。

官方话术听起来很抽象?

一句话总结就是:

> **原型模式就是用"复制"代替"重新创建"。**


二、为什么需要原型模式?

原型模式适用于以下场景:

1. 对象创建成本高

例如:

* 复杂对象构造

* 大量字段初始化

* IO 读取配置后生成对象

使用 clone 可以避免重复初始化。


2. 需要大量相似对象

比如:

* 游戏中大量相似的怪物对象

* 工厂中创建大量模板对象

* 配置对象复制并局部修改


3. 需要在运行时动态决定对象类型

不通过 if-else / new 语句

而通过原型列表(原型注册表)创建。


三、原型模式结构(UML 类图)

```

┌─────────────────────┐

│ Prototype 原型接口 │<────────┐

└─────────────────────┘ │ clone()

▲ │

│ │

┌───────────────────────┐ │

│ ConcretePrototype 具体原型类 │

└───────────────────────┘

│ clone()

┌──────────────────────┐

│ Client 客户端 │

└──────────────────────┘

```


四、Java 实现原型模式(浅拷贝版本)

下面用你的例子:**飞机 Plane 克隆**。

1. 原型接口

```java

public interface PlanePrototype extends Cloneable {

PlanePrototype clonePlanePrototype();

}

```


2. 具体原型类

```java

public class Plane implements PlanePrototype {

private String planeName;

private String planeId;

public Plane(String planeName, String planeId) {

this.planeName = planeName;

this.planeId = planeId;

}

@Override

public PlanePrototype clonePlanePrototype() {

try {

return (Plane) super.clone(); // 浅拷贝

} catch (CloneNotSupportedException e) {

throw new RuntimeException(e);

}

}

@Override

public String toString() {

return planeName + " - " + planeId;

}

}

```


3. 客户端调用

```java

public class ClientDemo {

public static void main(String[] args) {

Plane plane = new Plane("飞机1", "001");

Plane copy = (Plane) plane.clonePlanePrototype();

System.out.println(plane);

System.out.println(copy);

}

}

```

输出结果两个对象内容一样,但它们是 **不同的对象实例**。


五、浅拷贝 vs 深拷贝

浅拷贝:复制对象,但共享引用字段

如果对象内部有引用类型:

```java

class Plane {

Engine engine;

}

```

浅拷贝会导致:

```

plane.engine == copy.engine (true)

```

两个对象共享同一个 engine → 有风险。


深拷贝:复制对象 + 复制内部引用对象

深拷贝实现方式:

```java

@Override

public PlanePrototype clonePlanePrototype() {

try {

Plane plane = (Plane) super.clone();

plane.engine = this.engine.clone(); // 深拷贝引用对象

return plane;

} catch (Exception e) {

throw new RuntimeException(e);

}

}

```

适合复杂对象复制。


六、原型注册表(Prototype Manager)

当系统需要**按类型创建对象**时,可以把原型对象放到 Map 中:

```java

Map<String, PlanePrototype> registry = new HashMap<>();

registry.put("fighter", new Plane("战斗机", "F-001"));

registry.put("civil", new Plane("客机", "C-001"));

// 根据 key 复制原型

Plane clone = (Plane) registry.get("fighter").clonePlanePrototype();

```

→ 运行时动态决定"类"是什么,不需要写 new。

这是原型模式的进阶用法。


七、原型模式的优点

**提高对象创建性能**(避免重复构造)

**避免重复初始化**

**运行时动态生成对象**

**简化代码,只需 clone 就能创建大量对象**


八、原型模式的缺点

深拷贝复杂

clone() 容易滥用

Java 的 Cloneable 接口设计较老旧(不是最优雅)

如果对象内部结构复杂,深拷贝维护成本较高。


九、实际开发中何时使用原型模式?

推荐场景:

需要频繁创建结构类似的对象

创建成本高的对象(复杂构造、运行依赖)

配置类模板复制

游戏开发、图形系统等需要大量相似对象的场景

不推荐场景:

对象结构非常复杂

有大量需要深拷贝的对象

clone() 使用会降低代码可读性


十、总结

原型模式是一种简单却非常实用的设计模式,本质是:

> **用已有对象当作模板,通过克隆来创建新对象。**

优点是提升性能、减少 new 复杂对象的开销;缺点是深拷贝难维护。

对于 Java 开发来说,掌握浅拷贝 + 深拷贝 + Prototype 注册表,就已经足够应对绝大多数项目场景。

相关推荐
乐悠小码2 天前
Java设计模式精讲---04原型模式
java·设计模式·原型模式
火鸟25 天前
给予虚拟成像台尝鲜版十,完善支持HTML原型模式
原型模式·通用代码生成器·给予虚拟成像台·给予·html原型模式·快速原型·rust语言
乙己4076 天前
设计模式——原型模式(prototype)
设计模式·原型模式
仙人掌_lz7 天前
Multi-Agent的编排模式总结/ Parlant和LangGraph差异对比
人工智能·ai·llm·原型模式·rag·智能体
午安~婉9 天前
javaScript八股问题
开发语言·javascript·原型模式
火鸟211 天前
给予虚拟成像台尝鲜版九,支持 HTML 原型模式
html·原型模式·通用代码生成器·给予虚拟成像台·给予·html原型模式·快速原型
数据知道12 天前
Go语言设计模式:原型模式详解
设计模式·golang·原型模式
JS.Huang13 天前
【JavaScript】构造函数与 new 运算符
开发语言·javascript·原型模式
Yeniden13 天前
设计模式>原型模式大白话讲解:就像复印机,拿个原件一复印,就得到一模一样的新东西
java·设计模式·原型模式·1024程序员节