软件架构风格:给准架构师的“选型地图”

58 阅读7分钟

软件架构风格:给准架构师的“选型地图”

这一章想做一件事:帮你把常见架构模式,装进一个清晰的“脑内索引”。

我选了 5 大类、十几种软件架构风格,它们几乎覆盖了你日常工作能碰到的大部分系统形态:

  • 数据流风格
  • 调用返回风格
  • 独立构建风格
  • 虚拟机风格
  • 仓库风格

下面用技术博客的方式,帮你快速建立直觉:什么场景,优先往哪种风格上想。


一、数据流风格:一切皆“流”的世界

适用核心场景:有一条“主数据流”,经过多步加工

典型子风格有两种:

  • 批处理(Batch)

    • 把一段时间的数据先“攒起来”,再统一处理;
    • 特点:吞吐大、实时性弱、适合夜间任务、报表、T+1 结算等。
    • 例子:
      • 每天夜里跑的账单结算 / 对账任务;
      • 按小时 / 按天跑的数据仓库 ETL。
  • 管道-过滤器(Pipes & Filters)

    • 数据像水流一样,通过一系列“过滤器”(Filter)依次处理;
    • 每个过滤器专注做一件事,可以并行、可以复用;
    • 例子:
      • Linux 命令行 cat | grep | awk | sort
      • 日志收集 → 清洗 → 解析 → 聚合 → 入库的实时链路。

遇到这两类需求,可以优先考虑数据流风格

  • 原始数据 → 多步清洗 / 解析 / 聚合;
  • 大量数据,但对毫秒级延迟没那么敏感;
  • 可以接受“按窗口(时间/条数)”做处理。

二、调用返回风格:我们最熟悉的“按层调用”

适用核心场景:有一个“主流程”,通过函数 / 方法 / 层次逐步完成工作

三种典型形态:

  • 主程序-子程序(Main-Subroutine)

    • 面向过程:主程序调用一堆子过程,子过程完成后返回;
    • C 程序、简单脚本、工具类程序中非常常见。
  • 面向对象(OO)

    • 把状态和行为封装进对象里;
    • 通过对象之间的调用协作完成业务;
    • Java、C#、多数后端业务代码的常规写法。
  • 分层结构(Layered Architecture)

    • 典型如:控制层(Controller)→ 业务层(Service)→ 领域层 / 仓储层(Domain/Repository);
    • 或者表示层 / 应用层 / 领域层 / 基础设施层。

你日常写的大多数 Web / 后台服务,本质上都是这三种的组合。

当你遇到这样的需求:

  • 有清晰的“输入-处理-输出”主流程;
  • 可以自然地分出展示层 / 业务层 / 数据访问层;
  • 每一层都有明确职责边界;

就可以想到:本质是调用返回风格,只是用 OO + 分层结构把它组织得更清晰


三、独立构建风格:服务之间如何“互相打招呼”

适用核心问题:多个独立的模块 / 服务,要怎么通信更合适

有两大主流子风格:

  • 进程间通信(IPC)风格

    • 有明显的“调用者 / 被调用者”;
    • 通过 HTTP/REST、gRPC、RPC 框架等实现;
    • 适合:
      • 同步请求响应;
      • 对调用链路有明确的事务 / 一致性诉求。
  • 事件驱动 / 消息队列风格

    • 生产者只负责发送事件 / 消息,不关心谁来处理;
    • 消费者订阅感兴趣的事件,自主处理;
    • 异步、解耦、天然适合削峰填谷;
    • 适合:
      • 订单创建后触发积分、通知、风控等异步流程;
      • Webhook / 回调场景;
      • 业务对“最终一致性”可以接受。

如果你发现:

  • 模块越来越多,直接 HTTP 互调让耦合度飞涨;
  • 大量业务其实不需要同步强一致;

可以先问自己两个问题:

  • 哪些必须走 同步调用(IPC)
  • 哪些可以改为 事件驱动 / 消息通知

这个判断,往往就是你从“写服务”走向“做架构”的起点。


四、虚拟机风格:让“程序跑在程序里”

别被名字误导,这里的“虚拟机”,不只是 KVM/VMware 那种物理虚机,更重要的是像 JVM 这种“程序的运行环境”

两类典型子风格:

  • 解释器风格

    • 比如 JVM、Python 解释器、SQL 引擎;
    • 它们读你的“程序”(字节码、脚本、SQL),在一个虚拟环境中执行;
    • 好处:
      • 屏蔽底层平台差异;
      • 提供统一的运行时能力(GC、安全沙箱、JIT 优化等)。
  • 规则引擎 / 决策系统风格

    • 比如 Drools、各类业务规则平台;
    • 业务人员通过图形界面 / 规则 DSL 定义逻辑,规则引擎负责解释执行;
    • 常见于:
      • 营销优惠策略(满减、阶梯价、黑名单等);
      • 风控规则、审批流程策略。

当你遇到这些信号时,可以考虑虚拟机风格:

  • 业务规则经常变,不想每次都改代码、发版;
  • 希望把“规则配置权”交给业务,技术负责提供稳定执行环境;
  • 需要在不同平台(多语言、多操作系统)统一执行一套逻辑。

五、仓库风格:所有人共享的那块“大黑板”

核心问题:数据被多人 / 多模块共享时,怎么组织和管理?

有三种典型子风格:

  • 数据库风格(Repository as DB)

    • 最常见:集中式数据库、数据仓库;
    • 所有模块围绕一个(或一组)共享数据库组织读写;
    • 好处:
      • 数据一致性强;
      • 易于集中管理和分析;
    • 风险:
      • 容易演化成“超巨大共享表+存储过程地狱”;
      • 耦合度非常高,改一个地方牵一大片。
  • 超文本系统(Hypertext)

    • 更偏「文档、页面、链接」风格;
    • 早期的 Wiki、静态内容分发、CMS 系统中较多。
  • 黑板风格(Blackboard)

    • 少见但很有意思;
    • 想象一块共同的“黑板”:
      • 各种“专家模块”轮流在黑板上写入 / 读取信息;
      • 通过黑板上的状态推动问题逐步被解决;
    • 常用于:
      • 语音识别、复杂模式识别、组合推理系统。

对于普通业务系统,你更多会落在:

  • 关系型 / NoSQL 数据库 + 缓存;
  • 再通过领域划分 / 读写分离 / 事件溯源,控制“共享仓库”的复杂度。

黑板风格更多是“知道有这个武器”,未来碰到复杂 AI / 智能推理类场景时可以想到它。


六、把风格用在实战和面试上:三条建议

1. 遇到系统设计题,先在脑子里“归类到某个风格”

比如:

  • 问“Web 应用服务器如何处理 HTTP 报文和 SOAP 报文?”
    • 你可以答:核心是 管道-过滤器风格 + 分层结构风格
  • 问“操作系统 GUI 事件是怎么处理的?”
    • 可以谈:事件驱动(独立构建风格里的消息 / 事件子风格)
  • 问“Java 一次编写,到处运行靠的是什么?”
    • 很自然地说:虚拟机风格里的解释器(JVM)

2. 不要强行说“这个系统只有一种风格”

绝大多数真实系统都是多风格组合:

  • Web 应用 = 调用返回(分层) + 独立构建(REST 调用 / MQ 事件) + 仓库(数据库风格);
  • 大数据平台 = 数据流(批处理 + 流式管道) + 仓库(数据湖 / 数仓) + 虚拟机(SQL 引擎)。

你可以在回答中自然地说:

  • “主干用的是 X 风格,Y 部分比较适合 Z 风格,所以我们做了拆分。”

这会让你的答案看起来既专业又不死板。

3. 回去看自己的系统,给它做一次“风格体检”

可以自问:

  • 当前系统主要是哪些风格?有没有“用错风格”的地方?
  • 哪些同步调用其实可以改成事件驱动,降低耦合?
  • 哪些批任务其实可以“流式化”,减少延迟?
  • 哪些规则应该从代码里抽离到“规则引擎式”的虚拟机?

当你能用“风格语言”来描述和优化自己的系统,你就不只是“堆技术栈”,而是在有意识地做架构。