介绍一下软件开发中常见的几种的架构模式
一、经典基础架构模式
1. 分层架构(Layered Architecture)
-
核心思想:将系统按「职责」拆分为垂直分层(如表现层、业务逻辑层、数据访问层),层与层之间单向依赖(上层调用下层,下层不依赖上层)。
-
举个例子:工厂生产线 ------ 原料(数据)从 "原料采购层"(数据访问层)进入,经 "加工层"(业务逻辑层)处理,最后从 "成品展示层"(表现层)输出,每一层只做自己的事。
-
典型分层:
(以 Web 应用为例):
- 表现层(UI 层):用户交互(如页面、接口);
- 业务逻辑层(Service 层):核心业务规则(如订单计算、权限校验);
- 数据访问层(DAO 层):操作数据库(如查询、新增数据);
- 数据库层:存储数据。
-
适用场景:绝大多数常规应用(如管理系统、小型网站),结构清晰、易于维护。
2. 微服务架构(Microservices Architecture)
- 核心思想:将复杂系统拆分为多个「独立部署、松耦合、专注单一功能」的小型服务(如订单服务、用户服务、支付服务),服务间通过 API 通信。
- 举个例子:大型医院 ------ 挂号、问诊、化验、缴费是独立 "服务部门",各自独立运作,通过 "分诊台"(API 网关)协调,患者(用户)无需知道内部流程。
- 核心特点:服务独立部署(一个服务故障不影响整体)、技术栈灵活(不同服务可用药不同语言)、可按需扩容(热门服务单独加机器)。
- 适用场景:大型复杂应用(如电商平台、短视频 APP)、需要快速迭代、多团队协作的项目(BFF 常与微服务搭配使用)。
3. 单体架构(Monolithic Architecture)
- 核心思想:所有功能模块(如用户、订单、支付)打包在一个应用中,共享数据库,部署为一个整体。
- 举个例子:小餐馆 ------ 厨师、服务员、收银员是同一批人,所有流程在一个空间完成,无需复杂协调。
- 核心特点:开发简单(无需考虑服务间通信)、部署便捷(只部署一个应用)、初期成本低,但随着功能增加,应用会变得臃肿("巨石应用"),迭代和维护困难。
- 适用场景:小型应用(如个人博客、内部工具)、创业初期(快速验证产品)、功能简单且变更少的项目。
二、针对性解决特定问题的架构模式
1. 事件驱动架构(Event-Driven Architecture)
- 核心思想:系统由「事件」驱动(如 "订单创建""支付成功"),组件间不直接调用,而是通过发布 / 订阅(Pub/Sub)模式传递事件,实现解耦。
- 举个例子:快递物流 ------ 你(寄件人)将快递(事件)交给快递公司(事件总线),无需关心谁配送(订阅者),配送员(订阅者)收到快递后自动处理(如派送、签收),你只需要等待结果。
- 核心特点:松耦合(组件间无直接依赖)、异步处理(发布事件后无需等待响应)、可扩展性强(新增订阅者无需修改发布者)。
- 适用场景:需要解耦的复杂系统(如电商的 "下单 - 支付 - 发货 - 通知" 流程)、实时数据处理(如日志分析、监控告警)、事件触发多个后续操作的场景。
2. 领域驱动设计(DDD,Domain-Driven Design)
- 核心思想:以「业务领域」为核心(如 "电商领域" 的 "订单领域""商品领域"),将系统设计与业务逻辑深度绑定,通过 "领域模型"(如订单、商品、用户)抽象业务规则,实现业务与技术的统一。
- 举个例子:建筑设计 ------ 先根据用户需求(如 "家庭居住""办公")确定建筑的核心功能(领域模型),再设计户型、结构(技术实现),而不是先考虑用什么材料(技术框架)。
- 核心特点:业务逻辑清晰(代码结构与业务流程一致)、可维护性强(需求变更时只需修改对应领域模型)、适合复杂业务场景。
- 适用场景:业务逻辑复杂的大型应用(如金融系统、供应链管理系统)、多团队协作且需要统一业务认知的项目(常与微服务结合,一个领域对应一个或多个微服务)。
3. API 网关架构(API Gateway)
- 核心思想:在前端与后端服务之间增加一个 "网关" 层,统一接收前端请求,负责路由转发、权限校验、限流熔断、日志监控等共性功能。
- 举个例子:小区门禁 ------ 所有访客(前端请求)必须经过门禁(API 网关),门禁验证身份(权限校验)、登记信息(日志监控)、指引路线(路由转发),小区内的住户(后端服务)无需单独处理这些共性问题。
- 核心功能:路由转发(将请求转发到对应服务)、权限控制(统一验证 token)、限流熔断(防止恶意请求压垮服务)、数据转换(如前后端数据格式适配)。
- 适用场景:微服务架构(前端需要调用多个服务时,网关统一入口)、多端应用(Web/APP/ 小程序共用一个网关)、需要统一管控接口的项目(BFF 常与 API 网关搭配,网关负责共性功能,BFF 负责前端定制化适配)。
4. 服务网格(Service Mesh)
- 核心思想:将微服务间的「网络通信」(如服务发现、负载均衡、熔断降级、加密认证)从业务代码中剥离,交给专门的 "代理层"(Sidecar 代理)处理,业务代码只关注核心逻辑。
- 举个例子:城市交通系统 ------ 车辆(微服务)只需要专注于 "行驶"(业务逻辑),交通规则(服务发现)、红绿灯(熔断降级)、导航(负载均衡)由交通系统(Service Mesh)统一管控,无需司机(开发者)关心。
- 核心特点:解耦业务与通信逻辑、统一管控服务间交互、支持多语言(代理层与业务语言无关)。
- 适用场景:大型微服务集群(如数百个服务的系统)、多语言开发的微服务项目、需要精细化管控服务通信的场景(如金融级系统的安全认证、链路追踪)。
三、架构模式选择建议(快速匹配场景)
| 项目特点 / 需求 | 推荐架构模式 |
|---|---|
| 小型应用、快速验证、功能简单 | 单体架构 |
| 中大型应用、多团队协作、快速迭代 | 微服务架构(+ API 网关 + BFF) |
| 业务逻辑复杂、需要统一业务认知 | DDD(常与微服务结合) |
| 组件间需要解耦、异步处理多 | 事件驱动架构 |
| 微服务集群庞大、多语言开发 | 服务网格 |
| 常规应用、结构清晰、易于维护 | 分层架构 |
四、常见的几种「组合式架构模式」
实际开发中只用一种架构模式的情况很少,绝大部分的情况下使用的组合式架构模式,核心围绕「微服务 / 单体」为基础,搭配「分层架构」「API 网关」「BFF」等补充。
1.「单体架构 + 分层架构」(中小团队首选)
核心组合:
以「单体应用」为载体(所有功能打包部署),内部按「分层架构」拆分:
(表现层→业务逻辑层→数据访问层→数据库层)。
例:一个内部管理系统(如员工考勤、客户管理),所有功能在一个应用中,前端调用后端统一接口,后端按分层处理请求:
(接口接收参数→业务层校验规则→数据层操作数据库)。
为什么常用?
- 开发门槛低:无需考虑服务间通信、分布式问题,新手易上手;
- 维护成本低:部署只需打包一个应用,排查问题无需跨服务追踪;
- 适配场景广:80% 的中小应用(如创业初期产品、内部工具、小型 SaaS)都能满足,迭代速度不逊于微服务(初期功能少,无需拆分)。
适用场景
- 团队规模小(5 人以内)、技术栈统一(如全栈用 Java/Node.js);
- 功能相对固定(如线下门店管理系统)、用户量不大(日活 1 万以内);
- 快速验证产品(创业项目初期,先跑通业务再优化架构)。
2.「微服务架构 + 分层架构 + API 网关 + BFF」(中大型项目标配)
核心组合:
- 基础:按业务域拆分「微服务」(如用户服务、订单服务、支付服务),每个微服务内部仍用「分层架构」(保证单个服务的清晰性);
- 入口:用「API 网关」统一接收前端请求,处理权限校验、限流、路由转发(如把 "下单请求" 转发到订单服务);
- 适配:用「BFF」为不同前端(Web/APP/ 小程序)定制接口(如 APP 端需要简化的订单数据,BFF 聚合订单 + 用户 + 物流服务数据后返回)。
为什么常用?
- 解决大型项目痛点:多团队协作(不同团队负责不同微服务)、按需扩容(热门服务单独加机器)、故障隔离(一个服务挂了不影响整体);
- 兼容多端需求:BFF+API 网关完美适配 Web/APP/ 小程序,底层微服务无需改动;
- 云原生友好:微服务可部署在 K8s 上,配合容器化实现弹性伸缩,符合当前企业数字化转型趋势。
适用场景:
- 团队规模大(10 人以上,按业务域分工);
- 用户量高(日活 10 万 +)、功能复杂(如电商平台、短视频 APP、金融系统);
- 需要快速迭代(如互联网产品,每周更新版本)、多端同步开发。
落地实例:
某电商 APP 的架构:
- 微服务:商品服务(查商品信息)、订单服务(创建订单)、支付服务(处理付款)、库存服务(扣减库存);
- API 网关:接收 APP 的所有请求,验证用户 token,将 "创建订单" 请求转发到订单服务;
- BFF(APP 专属):聚合订单服务(订单号)+ 商品服务(商品名称 / 价格)+ 支付服务(支付状态)+ 物流服务(物流信息),返回给 APP 一个 "我的订单" 列表接口;
- 每个微服务内部:表现层(接口)→ 业务层(订单逻辑 / 支付校验)→ 数据层(操作数据库)。
3.「事件驱动架构」(微服务配套增强)
核心组合:
在「微服务架构」基础上,用「事件驱动」解决服务间异步通信问题(如 "支付成功" 后触发 "扣减库存""发送通知""生成物流单")。例:用户支付成功后,支付服务发布 "支付成功" 事件,库存服务、通知服务、物流服务订阅该事件,自动执行对应操作,无需支付服务逐一调用。
为什么常用?
- 解耦微服务:服务间无需知道对方地址,减少依赖(如新增 "积分服务" 订阅 "支付成功" 事件,无需修改支付服务);
- 支持异步场景:适合 "一个操作触发多个后续动作" 的场景(如电商下单后的一系列流程),提升系统吞吐量。
适用场景:
- 微服务间异步通信多(如订单→支付→库存→物流→通知);
- 不需要实时响应(如发送短信通知、生成报表);
- 高并发场景(如秒杀活动,避免同步调用导致的性能瓶颈)。
4.「DDD + 微服务」(复杂业务场景)
核心组合:
用「DDD(领域驱动设计)」指导「微服务拆分」,按业务领域(如 "订单领域""商品领域")拆分微服务,每个领域内按 "领域模型" 设计代码(如订单领域的 "订单聚合根""支付实体"),内部仍用分层架构。
为什么常用(仅限复杂业务)?
- 解决 "业务逻辑混乱" 问题:如金融系统(信贷、风控)、供应链管理系统,业务规则复杂,DDD 能让代码结构与业务流程一致,便于维护;
- 统一团队认知:产品、开发、测试围绕 "领域模型" 沟通,减少理解偏差。
适用场景:
- 业务逻辑复杂(如银行核心系统、保险理赔系统);
- 多团队协作(需要统一业务语言);
- 长期维护的大型项目(如企业级 SaaS)。
5. 实际开发中的架构选择逻辑
- 先判断「项目规模」:小型项目(单体 + 分层),中大型项目(微服务 + API 网关 + BFF + 分层);
- 再判断「业务复杂度」:业务简单(直接用基础组合),业务复杂(加 DDD),异步场景多(加事件驱动);
- 最后考虑「团队能力」:团队小、技术栈单一(选单体),团队大、有云原生经验(选微服务)。
五、总结
架构模式的核心是「解决特定场景的问题」:
- 初期用「单体架构」快速落地;
- 规模扩大后拆为「微服务架构」,搭配「API 网关」和「BFF」优化前后端交互;
- 业务复杂时用「DDD」梳理核心逻辑;
- 组件解耦、异步场景用「事件驱动架构」;
- 微服务集群庞大时用「服务网格」管控通信。
五、补充
1.补充介绍一下什么式BFF:
BFF(Backend For Frontend,前端专用后端) 是一种架构模式,核心是为特定前端应用(如 Web 端、移动端、小程序)定制专属的中间层服务,用于适配前端需求与后端底层服务(如微服务、数据库、第三方 API)。
核心定位与作用:
- 需求适配:前端(如移动端和 Web 端)对数据格式、接口粒度、请求频率的需求可能不同,BFF 层可针对性处理(如数据聚合、格式转换、字段过滤),避免前端直接调用多个底层服务并做复杂处理。例:电商 APP 的 "商品详情页" 需整合商品信息、库存、评价、推荐等多个微服务数据,BFF 层可统一调用这些服务,聚合后返回给前端一个简洁的接口,减少前端请求次数。
- 解耦与简化:隔离前端与底层服务的依赖,底层服务(如微服务拆分、接口变更)无需前端同步修改,只需调整 BFF 层适配;同时简化前端逻辑,让前端专注于 UI 渲染和交互。
- 性能优化:可在 BFF 层实现数据缓存、请求合并、限流降级等功能,提升前端响应速度。例:缓存热门商品数据,避免频繁调用底层微服务;合并多个前端请求为一个后端调用,减少网络开销。
典型应用场景:
- 多端适配:同一产品的 Web 端、iOS 端、Android 端需不同接口格式时,为每端配置专属 BFF。
- 微服务架构:前端需调用多个微服务才能完成一个功能时,BFF 层作为 "聚合器" 简化调用。
- 第三方 API 适配:第三方 API 返回格式不符合前端需求时,BFF 层进行转换和封装。
- 前端快速迭代:前端需求频繁变更时,通过修改 BFF 层避免影响底层核心服务。
注意事项:
- 避免过度设计:简单应用(如单端 + 少量接口)无需引入 BFF,否则增加复杂度。
- 性能开销:BFF 层是额外中间层,需做好缓存、异步处理,避免成为性能瓶颈。
- 职责边界:BFF 层不负责核心业务逻辑(如数据校验、事务处理),仅聚焦 "前端适配"。
简单介绍一个场景:
场景设定:
你(用户)去一家「多业态连锁餐厅」吃饭 ------ 这家餐厅的后厨是「微服务架构」:
- 「菜品微服务」:负责提供菜品信息(名称、价格、食材),不管库存;
- 「库存微服务」:负责查询食材是否充足(比如 "今天的牛排剩 3 份"),不了解菜品详情;
- 「优惠微服务」:负责计算折扣(比如 "会员满减""新用户立减"),只认菜品 ID;
- 「支付微服务」:负责收钱、生成订单,需要整合菜品、价格、优惠后的数据。
而你(前端)的需求很简单:点一份 "黑椒牛排",想一次性知道「这道菜多少钱、还有没有、能减多少、最终付多少」,然后直接付款。
没有 BFF 的情况:你得自己跑遍 "各个部门"
如果没有 BFF 这个 "专属服务员",你得亲自对接所有 "微服务后厨",流程是这样的:
- 你先找「菜品微服务」:"请问黑椒牛排的 ID 和价格是多少?" → 得到 "ID:101,价格:100 元";
- 你再找「库存微服务」:"ID101 的牛排还有吗?" → 得到 "剩 2 份";
- 你再找「优惠微服务」:"我是会员,ID101 的牛排能减多少?" → 得到 "立减 20 元";
- 你自己算最终价格:100-20=80 元;
- 最后找「支付微服务」:"我要付 80 元,订 ID101 的牛排" → 完成支付。
这就像前端直接调用多个微服务:需要发 4 次请求,自己处理数据聚合、计算,逻辑复杂还容易出错(比如算错优惠、漏查库存)。
有 BFF 的情况:你只对接 "专属服务员"
BFF 就像餐厅给你分配的「专属点餐服务员」,TA 知道你要什么,也知道各个 "后厨部门" 的职责,全程替你跑腿:
- 你只对 BFF(专属服务员)说一句话:"我要一份黑椒牛排,想知道价格、库存、优惠,然后付款"(前端只发 1 次请求给 BFF);
- BFF 转身对接各个 "微服务后厨":
- 问「菜品微服务」:"黑椒牛排的 ID 和价格?" → 得到 "ID101,100 元";
- 问「库存微服务」:"ID101 还有吗?" → 得到 "剩 2 份";
- 问「优惠微服务」:"会员买 ID101 能减多少?" → 得到 "立减 20 元";
- BFF 自己做数据整合:计算最终价格(100-20=80 元),把 "菜品名称、价格、库存、优惠金额、最终支付价" 打包成一个简单的 "套餐信息";
- BFF 把整合后的信息告诉你:"黑椒牛排 100 元,剩 2 份,会员立减 20 元,最终付 80 元"(BFF 返回 1 个聚合后的接口给前端);
- 你确认后,BFF 再帮你对接「支付微服务」完成付款(BFF 替前端处理后续依赖)。
对应技术场景的核心映射
| 餐厅场景 | 技术场景 | 核心作用 |
|---|---|---|
| 你(食客) | 前端应用(Web/APP) | 只需要简洁、聚合的结果 |
| 专属服务员(BFF) | BFF 层 | 适配前端需求,聚合后端服务 |
| 菜品 / 库存 / 优惠 / 支付后厨 | 底层微服务 / 第三方 API | 只负责单一、专业的功能 |
| 你只说 1 句话,服务员跑腿 | 前端只发 1 次请求 | 减少前端请求次数和逻辑复杂度 |
| 服务员整合信息后告诉你 | BFF 聚合数据后返回 | 前端无需处理复杂数据拼接 |
再延伸一下 "多端适配" 的作用(BFF 的另一个核心作用)
如果这家餐厅同时有「到店食客」(Web 端)、「外卖用户」(APP 端)、「团餐客户」(企业端):
- 到店食客需要知道「桌号、菜品上桌时间」;
- 外卖用户需要知道「配送费、预计送达时间」;
- 团餐客户需要知道「批量折扣、开发票流程」。
这时可以给每类用户配一个「专属服务员(BFF)」:
- 到店 BFF:聚合 "菜品 + 库存 + 桌号 + 上菜时间";
- 外卖 BFF:聚合 "菜品 + 库存 + 配送费 + 送达时间";
- 团餐 BFF:聚合 "菜品 + 批量库存 + 团餐折扣 + 开票接口"。
底层的 "菜品、库存" 微服务不变,只需要通过不同的 BFF 适配不同前端的需求 ------ 这就是 BFF "为前端定制" 的核心价值。
BFF 本质就是「前端的专属跑腿 + 翻译 + 整合员」,让前端不用关心后端有多少个服务、数据格式有多复杂,只需要专注于 "展示给用户看" 和 "和用户交互",后端也不用为了适配前端而改变自己的专业分工。