【软考系统架构设计师全链路通关实战】第 38 篇:层次式架构设计:MVC、MVP 与分层演化
本系列定位:以软考系统架构设计师(高级)考试为主线,语言无关的架构方法论视角,覆盖官方教程全部 20 章考点,按「综合知识 → 案例分析 → 论文」三科组织,每篇含考点精讲 + 真题规律 + 应试技巧 + Mermaid 图解。
本篇你将学到
- 层次式架构(分层架构)的原理、优点与固有缺点——案例分析论述题的作答骨架
- 三层架构(表现/业务/数据访问)到四层架构的演进逻辑
- MVC 的 Model/View/Controller 职责划分与交互时序
- MVP(Presenter 中介)与 MVVM(数据绑定)的演进动机与三代模式对比大表
- 工厂模式、单例模式、代理模式在分层架构中的落地方式(语言无关示例)
- 智联云商 v1 单体分层完整实例 + 层次式架构论文写作框架(为第 51 篇论文打底)
本篇是模块八「八类架构实战」的开篇,也是案例分析与论文双热点。
考点热力表
| 考点 | 综合知识 | 案例分析 | 论文 |
|---|---|---|---|
| 分层架构优缺点 | ★★ 常考概念 | ★★ 简答常考 | ★★ 论文论证段 |
| 三层/多层架构职责划分 | ★★★ 高频 | ★★ 补图/设计题 | ★★ |
| MVC 结构与交互 | ★★★ 高频概念 | ★★ 时序补图 | ★★ |
| MVP/MVVM 对比 | ★★ 近年升温 | ★ 偶现 | ★ |
| 设计模式在架构中落地 | ★★ 高频(结合工厂/单例/代理) | ★★ 代码填空 | ★★ 论文亮点素材 |
| 层次式架构论文 | ☆ | ☆ | ★★ 高频论文题之一 |
一、层次式架构:原理与优缺点
层次式架构(Layered Architecture)是第 22 篇调用返回风格家族中最重要的成员:系统按职责划分为若干层次,每层只与相邻层交互,上层调用下层服务,下层不得反向调用上层。OSI 七层模型、操作系统内核分层、数据库管理系统内部结构都是它的经典化身。
1.1 优点(论述题标准答案五条)
- 关注点分离:每层职责单一(表现只管交互、业务只管规则、数据访问只管存取),复杂问题分而治之。
- 可维护性:修改被封装在单层内,只要接口契约不变,其他层不动——这正是第 30 篇「可修改性战术:局部化变更」的结构化实现。
- 可复用性:每层是对下层功能的抽象,同一业务层可同时支撑 Web、App、开放 API 等多种表现层。
- 团队分工与并行开发:按层切分工作面,接口先行即可并行。
- 层间松耦合、利于替换:数据层从关系库换到 NoSQL,理论上只动数据访问层。
1.2 缺点(与优点同频出题,必须会写)
- 性能损耗:请求逐层传递,跨层调用带来额外的序列化/转换开销,不能「一步直达」。
- 级联修改:底层接口变更会沿调用链逐层向上波及,层次越多波及面越大。
- 并非所有需求都能干净分层:某些横切需求(安全、日志、事务)天然贯穿所有层,强行分层导致重复代码或依赖混乱。
- 层次过多导致过度设计:每加一层就加一份间接开销和维护成本。
答题技巧:案例题问「分层架构有何不足」,至少写性能损耗 + 级联修改两条;若题目给的是修改传播场景,直接把级联修改作为核心答案展开。
1.3 三层到四层演进
三层架构(表现/业务/数据访问)是最常考的基线,向四层演进有两条典型路线:
- 加「通用服务/应用层」:在业务层之上拆出「应用层/服务层」负责流程编排与 Facade,业务层专注领域规则——为后续第 39 篇 SOA 的服务抽象铺路。
- 加「持久化 ORM 层」:在业务与数据访问之间引入对象-关系映射,隔离领域模型与表结构。
判断层数的原则:每层必须有单一明确的抽象职责,且能被单独替换。
二、MVC 详解:职责与时序
MVC 把表现层内部再分为三个角色,是三层架构中表现层的最经典细化:
- Model(模型):封装业务数据与状态,以及相关的业务逻辑;模型不关心谁来展示它。广义上业务层 + 数据访问层就是后端视角的大 Model。
- View(视图):负责数据呈现,从模型读取数据渲染界面,本身不含业务逻辑。
- Controller(控制器):接收用户输入,解析请求、调用模型处理、选择返回哪个视图——是「调度员」而非「办事员」。
2.1 MVC 交互时序(案例补图题模板)
两个高频判定点:用户请求先进 Controller 而不是 View;View 可直接从 Model 取数渲染(MVC 允许 View 观察 Model),但 View 绝不写业务逻辑。补图题把箭头 2 画成「C→V」开头或让 V 承担计算,都是典型挖坑点。
三、MVP 与 MVVM:表现层模式的两代演进
MVC 在 Web/富客户端场景暴露的痛点:View 与 Model 之间直接耦合(箭头 5),视图难以单独测试与复用。两代演进都围绕「切断 View 与 Model 的联系」:
- MVP(Model-View-Presenter):引入Presenter 作为 View 与 Model 之间的唯一中介。View 变成被动的(Passive View)——只暴露接口(如 setText/showError),一切数据和刷新由 Presenter 主动推送;View 与 Model 完全隔离,可对 Presenter 做纯逻辑单元测试。代价是 Presenter 膨胀、接口爆炸(一个页面一套 View 接口)。
- MVVM(Model-View-ViewModel):ViewModel 同样隔离 View 与 Model,但依赖数据绑定机制:View 声明式绑定到 ViewModel 的可观察属性,属性变化自动刷新界面,消灭了 MVP 中大量手写「set 到 View」的样板代码。代价是绑定机制调试困难、内存泄漏风险(绑定未释放)。前端框架与桌面声明式 UI 普遍采用此模式。
3.1 MVC / MVP / MVVM 对比大表(必背)
| 维度 | MVC | MVP | MVVM |
|---|---|---|---|
| 中介角色 | Controller(调度) | Presenter(中介+推送) | ViewModel(中介+绑定) |
| View 与 Model 关系 | 允许直接交互(View 观察 Model) | 完全隔离 | 完全隔离 |
| View 的角色 | 相对主动(可观察 Model) | 被动(只暴露接口) | 声明式(绑定驱动) |
| 更新机制 | Controller 选视图 + View 取数 | Presenter 显式调 View 接口 | 数据绑定自动同步 |
| 可测试性 | 中 | 高(Presenter 可脱离 UI 测试) | 高(ViewModel 纯逻辑) |
| 样板代码 | 中 | 多(接口+手动刷新) | 少(绑定代劳) |
| 依赖方向 | View→Model 存在 | Presenter 持有 View 接口 | View 绑定 ViewModel |
| 典型场景 | 传统服务端 Web(请求-响应) | 表单复杂的 C/S、Android 早期 | 声明式前端、WPF/Compose |
| 演进动机 | — | 切断 View-Model 耦合、提升可测试性 | 消灭 Presenter 样板代码 |
记忆钩子:MVC 里 View 认识 Model,MVP 里谁也不认识谁(Presenter 搬砖),MVVM 里绑定牵线(数据自动流)。
四、设计模式在分层架构中的落地
设计模式是分层的「砖缝工艺」。综合知识爱考「某模式在架构中的用途」,案例爱考代码填空。三个最常与分层架构同框的模式:
4.1 工厂模式——层间解耦的装配器
上层依赖下层的接口而非具体实现,具体对象由工厂创建。业务层换一个数据源实现,只需改工厂配置,业务代码零改动——分层「可替换性」的保证机制。
// 数据访问层接口publicinterfaceOrderDao{OrderfindById(Stringid);}publicclassMysqlOrderDaoimplementsOrderDao{/* ... */}publicclassMongoOrderDaoimplementsOrderDao{/* ... */}// 简单工厂:业务层只认接口publicclassDaoFactory{publicstaticOrderDaocreateOrderDao(){return"mysql".equals(Config.get("dbType"))?newMysqlOrderDao():newMongoOrderDao();}}// 业务层:完全不感知具体实现publicclassOrderService{privatefinalOrderDaodao=DaoFactory.createOrderDao();publicOrderquery(Stringid){returndao.findById(id);}}4.2 单例模式——跨层共享受控实例
数据库连接池、配置中心、缓存管理器等跨层共享的资源管理器,用单例保证全局唯一实例,避免重复创建连接池造成资源浪费与状态不一致。
publicclassConnectionPool{privatestaticvolatileConnectionPoolinstance;// volatile 防指令重排privateConnectionPool(){/* 初始化连接池 */}// 私有构造堵死外部 newpublicstaticConnectionPoolgetInstance(){if(instance==null)// 双重检查锁synchronized(ConnectionPool.class){if(instance==null)instance=newConnectionPool();}returninstance;}}考点提示:私有构造器 + 静态方法获取实例是判别单例的标志;双重检查锁定中 volatile 的作用(禁止指令重排)是概念题加深点。
4.3 代理模式——横切关注点的层间织入
分层架构的痛点之一是横切需求(事务、日志、权限、懒加载)无处安放。代理模式在不改变真实类的前提下,把横切逻辑织入调用链:业务层调用的是Dao的代理对象,代理先开事务/记日志/查权限,再委托真实Dao执行。AOP(面向切面编程)本质就是动态代理的系统化。
publicclassTxOrderDaoProxyimplementsOrderDao{privatefinalOrderDaotarget;// 持有真实对象publicTxOrderDaoProxy(OrderDaotarget){this.target=target;}@OverridepublicOrderfindById(Stringid){Transactiontx=TxManager.begin();// 前置:开启事务(横切逻辑)try{Ordero=target.findById(id);// 委托真实对象tx.commit();returno;}catch(Exceptione){tx.rollback();// 异常回滚throwe;}}}三者定位一句话:工厂管「谁来实现」,单例管「只有一份」,代理管「调用前后加点料」——分别解决分层架构的可替换性、共享资源与横切关注点三个问题。
五、智联云商 v1:单体分层完整实例
智联云商电商平台第一版采用经典单体三层架构(后续第 39~41 篇将沿此演化):
落地要点映射(案例/论文可直接引用的因果链):
- 分层带来关注点分离:大促期间只扩表现层与应用实例,业务规则不动。
- 工厂模式支撑数据源可替换:商品检索从 MySQL 切到搜索引擎,业务层零修改。
- 代理模式统一事务与缓存:订单写操作走事务代理,商品读操作走缓存代理。
- 单例连接池控制资源:连接数可控,不随请求量线性膨胀。
- 遇到的分层之痛(论文「遇到的问题」素材):促销高峰期层间调用放大延迟(性能损耗)、一次数据表结构变更波及三个模块的数据访问层(级联修改)——这两个痛点正是第 39 篇走向 SOA、第 40 篇走向微服务的直接动机。
六、层次式架构论文写作框架(为第 51 篇打底)
「论层次架构风格/论 MVC 模式在某项目中的应用」是论文高频题。四段式骨架(详细方法论见第 51 篇):
- 项目背景(约 400 字):项目名称与规模、你的角色(架构师)、项目要解决的核心问题与质量目标(强调可维护性/团队协作),引出为何选择层次式架构——与第 33 篇 ATAM 的评估结论挂钩更显真实。
- 分层设计(约 900 字,主体):给出分层结构图(手绘分层数与各层职责);说明层间通信规则(仅相邻层交互、接口契约先行);重点写表现层 MVC/MVP 的选型理由与模式选型对比;说明工厂/单例/代理三个设计模式的落地位置与解决的问题。
- 遇到的问题与解决(约 700 字):写级联修改或性能损耗的真实案例、分析原因、给出对策(引入 Facade 收口、缓存代理、接口版本化),体现反思深度——这是拉开分数档位的段落。
- 效果与总结(约 500 字):可量化的效果(如需求平均交付周期缩短、缺陷率下降),并客观指出分层架构的局限与后续服务化演进计划,呼应第 39 篇。
写作红线:全文必须围绕自己项目的具体分层展开,通篇理论拼凑(只背本篇第一节优缺点)是论文二类卷的典型死因。
本篇小结
| 知识点 | 核心内容 |
|---|---|
| 分层优点 | 关注点分离、可维护、可复用、并行开发、利于替换 |
| 分层缺点 | 性能损耗、级联修改、横切需求难安放、过度分层 |
| 三层/四层 | 表现/业务/数据访问;演进加应用层或 ORM 层 |
| MVC | C 调度、M 数据、V 呈现;View 可直接观察 Model |
| MVP | Presenter 唯一中介、View 被动、完全隔离可测试 |
| MVVM | ViewModel + 数据绑定,消灭样板代码 |
| 模式落地 | 工厂=可替换,单例=唯一实例,代理=横切织入 |
| 论文骨架 | 背景→分层设计→问题与对策→量化效果 |
下篇预告
第 39 篇:面向服务架构 SOA:ESB、服务注册与 Web Service 实战
SOA 特征与参考架构、ESB 的作用、服务注册发现流程、WSDL/UDDI 实操、SOA 松耦合设计原则,以及 SOA 论文写作骨架——从单体分层走向服务化的第一步。
如果本篇内容对你有帮助,欢迎点赞收藏!有任何疑问,欢迎在评论区交流。