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 注册表,就已经足够应对绝大多数项目场景。

相关推荐
想吃火锅10052 天前
【前端手撕】instanceof
前端·javascript·原型模式
UXbot2 天前
帮助企业低门槛开展AI应用开发的平台推荐
前端·低代码·ui·交互·产品经理·原型模式·web app
UXbot2 天前
如何选择适合公司项目的UI设计工具?企业选型指南
前端·低代码·ui·团队开发·原型模式·设计规范·web app
UXbot2 天前
原型设计工具如何帮助新人快速进入产品行业?
前端·低代码·ui·交互·团队开发·原型模式·web app
sunny.day7 天前
js原型与原型链
开发语言·javascript·原型模式·js原型链
UXbot7 天前
AI网页开发工具能替代工具吗?5大平台对比
前端·人工智能·低代码·ui·原型模式·web app
weixin_307779138 天前
从“大海捞针”到“主动推理”:AI如何重塑云原生故障诊断的根因链
开发语言·人工智能·算法·自动化·原型模式
swordbob8 天前
prototype 注入到 singleton 里,prototype是否还是线程安全的
安全·spring·单例模式·原型模式
isNotNullX9 天前
企业数据中台建设,ETL工具选错了会踩哪些坑?
数据仓库·etl·原型模式
半个烧饼不加肉9 天前
JS 底层探究-- 普通函数和构造函数
开发语言·javascript·原型模式