文章目录
-
- 前言:为什么你需要学习工厂模式?
- 第一章:工厂模式是什么?用生活化例子理解
-
- [1.1 核心概念:专业的人做专业的事](#1.1 核心概念:专业的人做专业的事)
- [1.2 现实生活中的工厂模式](#1.2 现实生活中的工厂模式)
- 第二章:三种工厂模式详解
- 第三章:实际项目中的应用场景
-
- [3.1 数据库连接池](#3.1 数据库连接池)
- [3.2 日志系统](#3.2 日志系统)
- [3.3 支付网关](#3.3 支付网关)
- [3.4 游戏开发](#3.4 游戏开发)
- 第四章:如何选择正确的工厂模式?
- 第五章:最佳实践和常见陷阱
-
- [5.1 最佳实践 ✅](#5.1 最佳实践 ✅)
- [5.2 常见陷阱 ❌](#5.2 常见陷阱 ❌)
- 第六章:实战练习
- 总结
前言:为什么你需要学习工厂模式?
想象一下,如果你每次想吃披萨都要自己种小麦、养奶牛、建烤炉...这太疯狂了!在编程世界中,工厂模式就是帮我们避免这种"重复造轮子"的智慧。
学完本教程,你将:
- 真正理解工厂模式的核心思想
- 掌握三种工厂模式的应用场景
- 能在实际项目中正确使用工厂模式
- 写出更优雅、更易维护的代码
第一章:工厂模式是什么?用生活化例子理解
1.1 核心概念:专业的人做专业的事
工厂模式的本质: 把对象的创建过程"外包"给专门的工厂类,让使用者不需要关心对象是怎么被创建出来的。
1.2 现实生活中的工厂模式
场景1:点外卖 🍔
- 不用工厂模式:你要记住每个餐厅的电话、菜单、价格
- 用工厂模式:打开外卖APP → 选择品类 → 下单 → 等送达
场景2:买汽车 🚗
- 不用工厂模式:你自己造发动机、装轮胎、喷漆
- 用工厂模式:去4S店说"我要SUV" → 付钱 → 开走
场景3:装修房子 🏠
- 不用工厂模式:你自己买建材、找木工、找电工
- 用工厂模式:找装修公司 → 说明风格需求 → 等完工验收
第二章:三种工厂模式详解
2.1 简单工厂模式:像自动售货机
什么是简单工厂?
最简单的工厂形式,一个工厂类负责创建所有类型的对象。
代码示例:饮料售货机
java
// 产品接口
interface Drink {
void drink();
}
// 具体产品
class Cola implements Drink {
public void drink() {
System.out.println("喝可乐");
}
}
class Sprite implements Drink {
public void drink() {
System.out.println("喝雪碧");
}
}
// 简单工厂(售货机)
class DrinkFactory {
public Drink getDrink(String type) {
if ("cola".equals(type)) {
return new Cola();
} else if ("sprite".equals(type)) {
return new Sprite();
}
throw new IllegalArgumentException("未知饮料类型");
}
}
// 使用
public class Main {
public static void main(String[] args) {
DrinkFactory factory = new DrinkFactory();
// 顾客只需要知道要什么饮料,不用关心怎么生产的
Drink cola = factory.getDrink("cola");
cola.drink(); // 输出:喝可乐
Drink sprite = factory.getDrink("sprite");
sprite.drink(); // 输出:喝雪碧
}
}
适用场景:
- 产品类型较少且固定
- 不需要频繁添加新产品
- 适合小型项目或学习入门
优缺点:
- ✅ 优点:简单易用,代码直观
- ❌ 缺点:添加新产品需要修改工厂类,违反开闭原则
2.2 工厂方法模式:像专业餐厅联盟
什么是工厂方法?
定义一个创建对象的接口,但让子类决定实例化哪个类。工厂方法让类的实例化延迟到子类。
代码示例:餐厅系统
java
// 产品:食物
interface Food {
void cook();
}
class Pizza implements Food {
public void cook() {
System.out.println("烤制披萨");
}
}
class Sushi implements Food {
public void cook() {
System.out.println("制作寿司");
}
}
// 抽象工厂:餐厅
abstract class Restaurant {
// 点餐流程是固定的
public Food orderFood() {
Food food = createFood(); // 让具体餐厅决定做什么
food.cook();
System.out.println("食物准备好了!");
return food;
}
// 工厂方法:每个餐厅自己实现
protected abstract Food createFood();
}
// 具体工厂:披萨店
class PizzaRestaurant extends Restaurant {
protected Food createFood() {
return new Pizza();
}
}
// 具体工厂:寿司店
class SushiRestaurant extends Restaurant {
protected Food createFood() {
return new Sushi();
}
}
// 使用
public class Main {
public static void main(String[] args) {
// 想去披萨店
Restaurant pizzaShop = new PizzaRestaurant();
Food pizza = pizzaShop.orderFood();
// 输出:烤制披萨 → 食物准备好了!
// 想去寿司店
Restaurant sushiShop = new SushiRestaurant();
Food sushi = sushiShop.orderFood();
// 输出:制作寿司 → 食物准备好了!
}
}
适用场景:
- 产品类型可能会不断增加
- 需要更灵活的创建逻辑
- 不同产品有不同的创建过程
优缺点:
- ✅ 优点:符合开闭原则,扩展性好
- ❌ 缺点:类的数量会增加,复杂度稍高
2.3 抽象工厂模式:像整体装修公司
什么是抽象工厂?
创建相关或依赖对象的家族,而不需要明确指定具体类。
代码示例:UI主题系统
java
// 产品族:按钮
interface Button {
void render();
}
class WindowsButton implements Button {
public void render() {
System.out.println("渲染Windows风格按钮");
}
}
class MacButton implements Button {
public void render() {
System.out.println("渲染Mac风格按钮");
}
}
// 产品族:文本框
interface TextBox {
void display();
}
class WindowsTextBox implements TextBox {
public void display() {
System.out.println("显示Windows风格文本框");
}
}
class MacTextBox implements TextBox {
public void display() {
System.out.println("显示Mac风格文本框");
}
}
// 抽象工厂接口
interface GUIFactory {
Button createButton();
TextBox createTextBox();
}
// 具体工厂:Windows风格
class WindowsFactory implements GUIFactory {
public Button createButton() {
return new WindowsButton();
}
public TextBox createTextBox() {
return new WindowsTextBox();
}
}
// 具体工厂:Mac风格
class MacFactory implements GUIFactory {
public Button createButton() {
return new MacButton();
}
public TextBox createTextBox() {
return new MacTextBox();
}
}
// 使用
public class Application {
private Button button;
private TextBox textBox;
public Application(GUIFactory factory) {
button = factory.createButton();
textBox = factory.createTextBox();
}
public void render() {
button.render();
textBox.display();
}
}
// 主程序
public class Main {
public static void main(String[] args) {
// 创建Windows风格的应用
GUIFactory windowsFactory = new WindowsFactory();
Application windowsApp = new Application(windowsFactory);
windowsApp.render();
// 输出:渲染Windows风格按钮 → 显示Windows风格文本框
// 创建Mac风格的应用
GUIFactory macFactory = new MacFactory();
Application macApp = new Application(macFactory);
macApp.render();
// 输出:渲染Mac风格按钮 → 显示Mac风格文本框
}
}
适用场景:
- 需要创建相关产品家族
- 要保证产品之间的兼容性
- 系统需要切换不同的产品系列
优缺点:
- ✅ 优点:产品兼容性好,切换产品族容易
- ❌ 缺点:扩展新产品族比较困难
第三章:实际项目中的应用场景
3.1 数据库连接池
java
// 不用工厂模式
if (dbType.equals("MySQL")) {
connection = new MySQLConnection();
} else if (dbType.equals("Oracle")) {
connection = new OracleConnection();
}
// 使用工厂模式
connection = ConnectionFactory.createConnection(dbType);
3.2 日志系统
java
// 工厂帮你决定日志输出方式
Logger logger = LoggerFactory.getLogger(config.getLogType());
logger.info("用户登录成功");
3.3 支付网关
java
// 根据配置选择支付方式
Payment payment = PaymentFactory.createPayment(order.getPaymentMethod());
payment.process(amount);
3.4 游戏开发
java
// 根据关卡生成不同敌人
Enemy enemy = EnemyFactory.spawnEnemy(currentLevel);
enemy.attack();
第四章:如何选择正确的工厂模式?
决策流程图:
开始选择工厂模式
↓
需要创建单个产品还是产品家族?
↓
单个产品 → 产品类型是否固定?
↓
固定 → 简单工厂模式(简单直接)
不固定 → 工厂方法模式(易于扩展)
↓
产品家族 → 抽象工厂模式(保证兼容性)
选择指南:
| 场景 | 推荐模式 | 理由 |
|---|---|---|
| 小型工具类 | 简单工厂 | 简单够用 |
| 插件系统 | 工厂方法 | 易于扩展新插件 |
| 跨平台UI | 抽象工厂 | 保证界面风格一致 |
| 数据访问层 | 工厂方法 | 支持多种数据库 |
| 游戏物品系统 | 抽象工厂 | 装备套装效果 |
第五章:最佳实践和常见陷阱
5.1 最佳实践 ✅
-
遵循单一职责原则
- 工厂类只负责创建对象
- 业务逻辑放在产品类中
-
使用接口编程
- 针对接口编程,而不是实现
- 提高代码的灵活性
-
合理使用配置
- 通过配置文件决定创建哪种产品
- 避免硬编码
5.2 常见陷阱 ❌
-
过度设计
java// 不要这样:简单对象也用复杂工厂 String str = StringFactory.createString("hello"); // 应该这样:直接创建 String str = "hello"; -
工厂类过于庞大
- 如果一个工厂类有太多if-else,考虑拆分成多个工厂
-
忽略异常处理
java// 不好的做法 public Product createProduct(String type) { if ("A".equals(type)) return new ProductA(); return null; // 可能返回null } // 好的做法 public Product createProduct(String type) { if ("A".equals(type)) return new ProductA(); throw new IllegalArgumentException("不支持的产品类型: " + type); }
第六章:实战练习
练习1:简单的通知系统
创建一个通知工厂,支持邮件通知、短信通知、推送通知。
练习2:跨平台文件对话框
使用抽象工厂模式创建Windows和Mac风格的打开/保存文件对话框。
练习3:游戏武器系统
实现一个武器工厂,能够创建不同稀有度(普通、稀有、史诗)的武器。
总结
工厂模式的核心价值在于解耦 和封装。通过本教程的学习,你应该能够:
- 理解三种工厂模式的区别和应用场景
- 在实际项目中正确选择和使用工厂模式
- 写出更清晰、更易维护的代码
记住:不要重复造轮子,让专业的工厂来帮你创建对象!
如果有任何问题,欢迎随时提问!Happy Coding! 🚀