2025/9/16日 每日总结 简单工厂模式实战:模拟女娲造人场景
简单工厂模式实战:模拟女娲造人场景
设计模式是面向对象编程中的"武功秘籍",而简单工厂模式作为创建型模式的入门经典,以其简洁的结构和实用的功能,成为解决对象创建问题的常用方案。本文将通过"女娲造人"这一趣味场景,带你深入理解简单工厂模式的核心思想、结构组成与实际应用。
一、模式核心:为什么需要简单工厂?
在编程中,我们经常会遇到"根据不同条件创建不同对象"的需求。如果直接在业务代码中通过new关键字创建对象,会导致对象创建与使用高度耦合,不仅代码冗余,还难以维护——当需要新增对象类型时,必须修改原有业务逻辑。
简单工厂模式的核心动机的就是将对象的创建过程封装起来,通过一个统一的"工厂"类来负责对象实例化,客户端只需传入指定参数,无需关心对象创建的细节。这种设计实现了"创建与使用分离",让代码更具灵活性和可维护性。
二、场景分析:女娲造人需求拆解
我们需要模拟这样的场景:
-
女娲(创建者)能造出三种"人":男人(Man)、女人(Woman)、机器人(Robot)
-
客户端传入参数(M/W/R),女娲返回对应的对象
-
所有"人"都具备"被创造"的行为(create方法)
根据简单工厂模式的设计思路,我们可以将角色划分为三类:
-
抽象产品(Person):定义所有具体产品的公共接口
-
具体产品(Man/Woman/Robot):实现抽象产品接口,是工厂创建的目标
-
工厂类(Nvwa):根据参数逻辑,负责创建并返回具体产品实例
三、代码实现:一步步构建简单工厂
1. 定义抽象产品接口(Person)
抽象产品是所有具体产品的父类,定义了公共行为规范。这里我们通过接口声明create()方法,所有"人"都必须实现该方法。
// 抽象产品接口:定义公共行为
public interface Person {
void create();
}
2. 实现具体产品类
分别创建男人、女人、机器人三个具体产品类,实现Person接口并覆写create()方法,定义各自的"被创造"逻辑。
// 具体产品:男人
public class Man implements Person {
@Override
public void create() {
System.out.println("女娲造了一个男人");
}
}
// 具体产品:女人
public class Woman implements Person {
@Override
public void create() {
System.out.println("女娲造了一个女人");
}
}
// 具体产品:机器人
public class Robot implements Person {
@Override
public void create() {
System.out.println("女娲造了一个机器人");
}
}
3. 编写工厂类(Nvwa)
工厂类是简单工厂模式的核心,通过静态方法getPerson()接收参数,根据参数类型判断并创建对应的具体产品实例。这里使用equalsIgnoreCase()实现参数大小写兼容,增强灵活性。
// 工厂类:负责对象创建逻辑
public class Nvwa {
// 静态工厂方法:根据参数返回具体产品
public static Person getPerson(String type) throws Exception {
if (type == null || type.isEmpty()) {
throw new Exception("请输入有效参数(M/W/R)");
}
switch (type.toUpperCase()) {
case "M":
return new Man();
case "W":
return new Woman();
case "R":
return new Robot();
default:
throw new Exception("对不起,不能造该类人!支持的类型:M(男人)、W(女人)、R(机器人)");
}
}
}
### 4. 测试类验证
编写测试类,模拟客户端调用工厂类创建对象。通过输入不同参数,验证工厂是否能正确返回对应的产品实例并执行方法。
```java
import java.util.Scanner;
// 测试类:客户端调用示例
public class Test {
public static void main(String[] args) {
Scanner scanner = new Scanner(System.in);
System.out.print("请输入参数(M/W/R):");
String type = scanner.nextLine();
try {
// 调用工厂类创建对象,无需直接new具体产品
Person person = Nvwa.getPerson(type);
person.create(); // 执行产品的具体行为
} catch (Exception e) {
System.out.println("错误信息:" + e.getMessage());
} finally {
scanner.close();
}
}
}
5. 运行结果示例
// 输入M时输出
请输入参数(M/W/R):M
女娲造了一个男人
// 输入W时输出
请输入参数(M/W/R):W
女娲造了一个女人
// 输入无效参数时输出
请输入参数(M/W/R):X
错误信息:对不起,不能造该类人!支持的类型:M(男人)、W(女人)、R(机器人)
四、可视化类图设计
通过类图可以更清晰地展示简单工厂模式的结构关系:
┌───────────────┐
│ Person │ <-- 抽象产品接口
│───────────────│
│ + create(): void │
└───────────────┘
↑
│ 实现
┌───────────────┐ ┌───────────────┐ ┌───────────────┐
│ Man │ │ Woman │ │ Robot │ <-- 具体产品类
│───────────────│ │───────────────│ │───────────────│
│ + create(): void │ │ + create(): void │ │ + create(): void │
└───────────────┘ └───────────────┘ └───────────────┘
↑ ↑ ↑
│ │ │ 创建
┌───────────────┐
│ Nvwa │ <-- 工厂类
│───────────────│
│ + getPerson(type: String): Person │
└───────────────┘
五、模式优缺点与适用场景
优点
-
解耦:分离对象的创建与使用,客户端无需知道对象创建的细节,只需关注业务逻辑
-
简化代码:集中管理对象创建逻辑,避免代码冗余
-
灵活性高:修改对象创建逻辑时,只需修改工厂类,无需改动客户端代码
-
便于扩展:新增产品时,只需新增具体产品类并修改工厂类的判断逻辑(符合开闭原则的部分要求)
缺点
-
工厂类职责过重:所有产品的创建逻辑都集中在一个工厂类中,当产品数量过多时,工厂类会变得庞大复杂,难以维护
-
违反开闭原则:新增产品时需要修改工厂类的判断逻辑(如switch/case语句),而非仅新增代码
-
静态工厂方法限制:工厂方法通常为静态,无法通过继承扩展工厂类的功能
适用场景
-
产品种类较少且相对稳定,不会频繁新增产品
-
客户端不需要知道产品的创建细节,只需通过参数获取对应产品
-
希望统一管理对象创建逻辑,降低客户端与具体产品的耦合度
六、扩展与优化:HTML交互式演示
为了更直观地展示简单工厂模式的效果,我们可以通过HTML+JavaScript实现一个交互式演示页面。核心逻辑与Java版本一致,通过工厂函数根据用户输入参数创建不同的"人"对象。
<!DOCTYPE html>
<html lang="zh-CN">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>简单工厂模式 - 女娲造人</title>
<style>
/* 样式省略,保持页面美观 */
</style>
</head>
<body>
<div class="container">
<header>
<h1>简单工厂模式 - 女娲造人</h1>
<p>输入参数 M/W/R,体验女娲造人过程</p>
</header>
<div class="demo-section">
<input type="text" id="typeInput" placeholder="M/W/R" maxlength="1">
<button onclick="createPerson()">开始造人</button>
<div id="result" class="result"></div>
</div>
</div>
<script>
// 抽象产品接口(JavaScript中通过类模拟)
class Person {
create() {
throw new Error("子类必须实现create方法");
}
}
// 具体产品类
class Man extends Person {
create() {
return "女娲造了一个男人";
}
}
class Woman extends Person {
create() {
return "女娲造了一个女人";
}
}
class Robot extends Person {
create() {
return "女娲造了一个机器人";
}
}
// 工厂类
class Nvwa {
static getPerson(type) {
const upperType = type.toUpperCase();
switch (upperType) {
case "M": return new Man();
case "W": return new Woman();
case "R": return new Robot();
default: throw new Error("无效参数!支持 M(男人)、W(女人)、R(机器人)");
}
}
}
// 交互逻辑
function createPerson() {
const type = document.getElementById("typeInput").value;
const resultDiv = document.getElementById("result");
try {
if (!type) throw new Error("请输入参数");
const person = Nvwa.getPerson(type);
resultDiv.textContent = person.create();
resultDiv.style.color = "#28a745";
} catch (e) {
resultDiv.textContent = e.message;
resultDiv.style.color = "#dc3545";
}
}
</script>
</body>
</html>
七、总结与思考
简单工厂模式虽然结构简单,但蕴含了创建型模式的核心思想——封装对象创建。通过本文的"女娲造人"案例,我们可以发现:
-
简单工厂模式的核心是"工厂类",它承担了对象创建的全部责任,客户端只需"下单"(传入参数)即可获得产品
-
该模式适用于产品种类不多、变化不频繁的场景,如工具类创建、配置对象生成等
-
当产品种类繁多且频繁变化时,简单工厂模式会暴露其缺点,此时可以考虑工厂方法模式或抽象工厂模式进行优化
在实际开发中,我们不必拘泥于设计模式的固定形式,而应根据具体需求灵活运用。简单工厂模式作为入门级设计模式,是理解更复杂模式(如工厂方法、抽象工厂)的基础,掌握它能帮助我们写出更优雅、更易维护的代码。
通过本次实战,深刻体会到"设计模式是解决特定问题的最佳实践"——好的设计模式能让代码结构更清晰、耦合更低,这也是每个开发者从"能实现功能"到"写出高质量代码"的必经之路。

浙公网安备 33010602011771号