找回密码
立即注册
搜索
热搜: Java Python Linux Go
发回帖 发新帖

4211

积分

0

好友

589

主题
发表于 3 天前 | 查看: 30| 回复: 0

云栈社区的技术分享中,我们常常探讨如何让代码更优雅、更易维护。今天,我们来聊聊一个能有效帮你管理对象创建、告别混乱if-else的经典模式——工厂模式

它的核心思想非常简单,就是把对象创建的逻辑,从业务代码里抽出来,交给专门的工厂类。你的业务代码只需要告诉工厂“我要什么”,就能拿到现成的对象,只负责用,不操心怎么造。这就好比点外卖,你只管下单,厨房怎么做、怎么打包,你完全不用管。

为什么要用工厂模式?

直接在业务代码里随处 new 对象,看似直接,实则暗藏两个“坑”:

  • 创建逻辑重复且分散:同一个类的 new 操作,可能在 Controller、Service、定时任务里到处都是。哪天这个类的构造方式需要调整(比如初始化时要多传一个参数),你就得把代码里所有 new 的地方翻出来改一遍,费时费力还容易遗漏。
  • 业务代码变臃肿:核心业务逻辑里混入了一堆判断类型、组装参数、创建对象的代码,可读性变差,后期定位问题也像大海捞针。

工厂模式的价值,正是为了解决这些问题。它将变化的部分(对象创建)封装起来,让稳定的部分(业务逻辑)保持干净。

一、简单工厂模式:快速上手的“万能工厂”

简单工厂的核心是 一个工厂类,包揽所有产品的创建。它非常适合产品类型固定、后期很少新增或变更的场景。

1. 定义抽象产品:日志接口

首先,我们定义一个所有日志实现都必须遵守的契约(接口),确保行为一致。

public interface Logger {
    void log(String message);
}

2. 实现具体产品:两种日志

分别实现控制台日志和文件日志,每个类职责单一。

// 控制台日志
public class ConsoleLogger implements Logger {
    @Override
    public void log(String message) {
        System.out.println("[控制台日志] " + message);
    }
}

// 文件日志(实际项目会包含真实的文件操作,此处为简化演示)
public class FileLogger implements Logger {
    @Override
    public void log(String message) {
        System.out.println("[文件日志] " + message);
    }
}

3. 核心工厂:集中管理创建逻辑

这是简单工厂的核心,所有的创建判断都集中在此。

public class LoggerFactory {
    // 静态方法,直接调用,无需实例化工厂
    public static Logger getLogger(String type) {
        if ("console".equals(type)) {
            return new ConsoleLogger();
        } else if ("file".equals(type)) {
            return new FileLogger();
        }
        // 不支持的类型,直接抛异常快速失败
        throw new IllegalArgumentException("不支持的日志类型:" + type);
    }
}

4. 客户端调用

业务代码变得非常简洁。

public class SimpleFactoryDemo {
    public static void main(String[] args) {
        Logger consoleLog = LoggerFactory.getLogger("console");
        consoleLog.log("用户登录成功,ID:10086");

        Logger fileLog = LoggerFactory.getLogger("file");
        fileLog.log("订单支付完成,编号:20260306001");
    }
}

运行结果

[控制台日志] 用户登录成功,ID:10086
[文件日志] 订单支付完成,编号:20260306001

简单工厂的优劣势与适用场景

  • 优点:代码简单直观,集中管理创建逻辑,有效减少了重复代码。客户端完全不用关心对象是如何被创建出来的。
  • 缺点违反了“开闭原则”。如果想新增一种日志(比如数据库日志),就必须修改 LoggerFactory 类中的 if-else 逻辑,这可能会影响原有的稳定代码。
  • 适用场景:产品类型固定,后期几乎不会新增的基础组件。例如,项目初期确定的少数几种第三方服务客户端、固定的加密算法实现等。

二、工厂方法模式:支持扩展的“专业产线”

简单工厂的缺点(改代码才能加产品)在需要频繁扩展的系统里会很头疼。工厂方法模式正是为此而生,其核心思想是 一个产品对应一个工厂,将对象的创建延迟到具体的工厂子类中去完成

我们延续日志的例子,目标是:新增一个数据库日志,完全不需要修改任何现有代码。

1. 复用原有产品

Logger 接口、ConsoleLoggerFileLogger 这些现有代码完全不用动。

2. 新增产品:数据库日志

只需新增这个产品类。

// 新增的数据库日志实现
public class DbLogger implements Logger {
    @Override
    public void log(String message) {
        System.out.println("[数据库日志] " + message);
    }
}

3. 定义抽象工厂:规范创建行为

不再是具体的类,而是一个接口,声明创建方法。

// 抽象日志工厂,只声明创建方法
public interface LoggerFactory {
    Logger createLogger();
}

4. 实现具体工厂:各司其职

每个产品都有自己专属的工厂。

// 控制台日志工厂
public class ConsoleLoggerFactory implements LoggerFactory {
    @Override
    public Logger createLogger() {
        return new ConsoleLogger();
    }
}

// 文件日志工厂
public class FileLoggerFactory implements LoggerFactory {
    @Override
    public Logger createLogger() {
        return new FileLogger();
    }
}

// 数据库日志工厂(新增,不碰任何老代码)
public class DbLoggerFactory implements LoggerFactory {
    @Override
    public Logger createLogger() {
        return new DbLogger();
    }
}

5. 客户端调用:面向接口编程

public class FactoryMethodDemo {
    public static void main(String[] args) {
        // 控制台日志
        LoggerFactory consoleFactory = new ConsoleLoggerFactory();
        Logger consoleLog = consoleFactory.createLogger();
        consoleLog.log("系统启动完成,端口:8080");

        // 新增的数据库日志
        LoggerFactory dbFactory = new DbLoggerFactory();
        Logger dbLog = dbFactory.createLogger();
        dbLog.log("用户注册成功,手机号:13800138000");
    }
}

工厂方法模式严格遵循了“开闭原则”,新增产品时,你只需要增加“产品类+工厂类”,原有代码丝毫无需改动,扩展性极佳,也更安全。当然,它的代价是会产生大量的工厂类,在设计模式的运用中需要权衡。

适用场景:产品类型需要频繁新增或变更,且项目非常注重可扩展性和维护性的中大型系统。

三、实战指南:如何选择这两种模式?

了解了原理,在实际的Java项目中该如何选择呢?一张表帮你快速决策:

对比项 简单工厂模式 工厂方法模式
核心思想 一个“万能”工厂集中创建 一个产品对应一个“专业”工厂
新增产品 必须修改工厂类的创建逻辑(如if-else 仅需新增产品类和工厂类,不修改老代码
代码复杂度 低,结构简单,适合快速开发 高,类数量增多,适合规范开发
设计原则 违反开闭原则 符合开闭原则
适用场景 产品类型固定,后期很少变更 产品类型频繁新增,系统注重可扩展性

结合日常开发场景

  1. 支付模块:项目初期只有微信、支付宝支付,为了快速上线,可以采用简单工厂。后续业务扩展,需要接入银联、云闪付等多种支付渠道时,就应该重构升级为工厂方法模式,以应对未来的变化。
  2. 消息推送中心:一开始只支持短信和微信模板消息,用简单工厂足矣。当产品要求增加邮件、APP站内信、钉钉机器人等推送方式时,工厂方法模式就能让扩展变得轻松且安全。

实际上,Spring框架的核心容器 BeanFactory / ApplicationContext 就是一个超级强化版的工厂,它负责创建、组装和管理我们应用中的所有Bean对象,是工厂模式在框架层面的极致体现。

总结

工厂模式的核心价值在于解耦——将对象的创建与使用分离。无论选择简单工厂还是工厂方法,目的都是让业务逻辑更清晰、代码更易维护、系统更具弹性。下次当你在代码中看到即将失控的 if-elseswitch 时,不妨考虑一下,是否可以用工厂模式来优雅地解决它。




上一篇:AI生成视频技术突围:创作者如何用低成本实现千万播放?
下一篇:《失落星舰:马拉松》评测:为何它不像传统搜打撤,射击游戏出路在哪?
您需要登录后才可以回帖 登录 | 立即注册

手机版|小黑屋|网站地图|云栈社区 ( 苏ICP备2022046150号-2 )

GMT+8, 2026-3-10 11:12 , Processed in 0.603033 second(s), 40 queries , Gzip On.

Powered by Discuz! X3.5

© 2025-2026 云栈社区.

快速回复 返回顶部 返回列表