程序员的高阶价值究竟是什么?在我看来,绝不仅仅是 "写代码的执行者",更应该成长为"设计者、决策者、整合者 "。尤其在AI时代,写代码门槛被大幅拉平,这些高阶能力愈发重要:AI生成代码,我们来搭建系统骨架,成为优秀的架构与系统设计者;我们要精准理解需求、定义需求与问题边界,把模糊的业务诉求转化为清晰的技术方案;我们要成为数据模型工程与pipeline的搭建者。一句话总结:懂业务、会架构、能工程化、善用AI、能控风险。下面,我将继续围绕"搭系统骨架"这一核心,深入聊聊移动端架构。
一、谈移动端架构我们在讨论什么
很多移动端应用,从用户路径看,无非是:调接口 → 展示列表/详情 → 跳转 → 再调接口 → 再展示。若只停留在这一层,似乎"没什么可架构的"。但真正决定产品能否长期迭代、团队能否并行开发、线上问题能否快速收敛的,是支撑这些路径的基础设施与协作方式。
结合业界常见实践,讨论移动端架构时,通常至少覆盖以下几类问题:
| 维度 | 典型问题 |
|---|---|
| 网络 | 如何安全、一致地调用 API?弱网、超时、重试、缓存、鉴权如何统一? |
| 界面 | 页面/模块如何组织,才能降低耦合、让业务开发专注需求而非胶水代码? |
| 持久化 | 本地数据如何分层(缓存 vs 源数据)、如何控制读写路径与一致性? |
| 动态化 | 审核周期下,如何灰度、热修、配置驱动(在合规与风险可控前提下)? |
| 工程与协作 | 模块化边界、CI/CD、埋点与实验、多团队协作时的接口契约 |
下面用一张简图概括用户眼中的路径 与架构要垫的底子 之间的关系:

架构工作,就是把这条环路上的重复模式抽成稳定层,把易变部分留给业务,并把观测、测试、演进成本算进去。
二、架构设计的一种方法(自顶向下 + 自底向上 + 度量)
可概括为六步法则:
-
明确问题与"对业务方的充要条件 "
架构暴露给业务的接口,应尽可能接近"业务真正需要的最小信息"。例如:翻页不必强行暴露"当前页码",可提供 loadNextPage();读文件对上层不必暴露 buffer/size 等底层细节。参数越少、语义越清晰,替换实现与演进成本越低。
-
问题分类、分模块
按职责切分:网络、路由、UI 容器、领域模型、存储、埋点等,避免"一个大类干所有事"。
-
理清依赖、统一"交流规范 "
同类型问题用同一套模式(例如统一用单向数据流,或统一用 Repository 作为数据唯一入口),避免同一项目里多种哲学并存导致认知负担。
-
推演未来
国际化、深色模式、平板适配、离线、A/B、多业务线并入同一 App 等,是否在模块边界上留有余地。
-
自底向上实现:先搞定最基础的依赖
先落地网络契约、错误模型、日志与路由等"地基",再堆业务;实现过程中敢于调整设计。
-
打点、单测、性能数据,再优化
客户端性能往往"重要但不必事事放在第一位 "------在体验可接受的前提下,优先保证迭代效率与可维护性;优化应绑定度量(启动、首屏、滑动掉帧、包体积、内存峰值等)。
一句话:自顶向下想清楚模块与边界,自底向上用真实代码验证,用数据驱动优化。
三、分层:"几层"是结果,不是起点
不要为了三层 / 四层而三层 / 四层。更稳妥的做法是:
- 先列出要解决的问题与模块;
- 再归类;
- 归类后若自然形成三层,就称为三层;若某一层过大,再拆出第四层(例如把网络从"数据层"中独立出来)。
从角色角度,很多系统都可以粗分为三类(数据管理者 / 数据加工者 / 数据展示者):
- 数据与状态从哪里来、存哪里(远程、本地、内存)
- 业务规则与用例(校验、组合、权限)
- 如何呈现与交互(UI、导航、动画)
这与 MVC / MVVM / MVI / Clean 等并不矛盾:前者偏模块归类,后者偏数据流动方向。实际项目里常常是(模块分层 + 某种 UI 数据流模式)的组合。

四、什么是"好架构"
4.1 结构清晰,慎用"万能目录"
代码整齐、分类明确 :一个模块 / 类最好只做一类事(单一职责原则)。
谨慎使用 Common / Core 大杂烩:小模块可以独立成极小模块(甚至只有两个文件),用依赖声明明确引用,而不是全部扔进 Common。Common 容易纵容横向依赖与粒度失控,后期拆分成本极高(含多 App、多 Pod 场景)。
4.2 低文档依赖的上手体验
API 命名即文档 :类型明确,避免滥用 id / 弱类型;回调方式在同一域内保持一致。
举例(Objective-C 风格,思想适用于 Kotlin/Swift):
objectivec
// 更可读:语义与类型清晰
- (NSDictionary *)exifDataOfImage:(UIImage *)image atIndexPath:(NSIndexPath *)indexPath;
// 应避免:泛型弱、语义含糊、无关参数(如把 delegate 塞进纯数据函数)
- (id)exifData:(UIImage *)image position:(id)indexPath callback:(id<ErrorDelegate>)delegate;
Kotlin/Swift 侧同理:少用 Any、少用"万能回调",用 Result、密封类错误、sealed interface 等表达状态。
4.3 思路统一
同一种问题(列表分页、登录态失效、图片加载)应用同一套基础设施,避免"这个页面用 A 库、那个页面手写一套"。
4.4 依赖方向:减少横向与跨层
模块间尽量不横向互相穿透;依赖尽量单向。
跨层访问(例如网络层细节直接驱动具体 Widget)应极少出现;必要时应通过明确的事件总线或领域层收口,并限制使用场景。
4.5 该收权处收权,该放权处放权
对一致性、安全、数据完整性要强约束(例如统一写库入口、统一鉴权刷新)。
对产品实验、UI 细节、小范围策略可保留扩展点(策略注入、插件接口等)。
4.6 可测试、可扩展
核心业务与 UI 解耦,便于单测与 UI 测试;网络与存储可替换为 Fake。
模块边界清晰时,**加新功能像"插模块"**而不是"改全局"。
4.7 适度超前
技术超前:关注平台演进(如 SwiftUI/Compose、并发模型)。
产品超前:与产品沟通中长期形态,在路由、配置、多租户等方面预留空间------不等于提前实现。
4.8 接口少、参数少
在满足充要条件前提下,收敛入口;多出来的往往是历史包袱或设计犹豫。
4.9 性能:重要,但在客户端常"排在务实优先级之后"
移动端设备性能总体较好,很多微优化用户无感;更应关注首屏、卡顿、耗电、包体积、后台行为 等可感知指标。
性能优化应分域(网络、渲染、存储、图片)并有数据。
5. 四大技术域:架构落在哪里
5.1 网络层
统一 :Base URL、拦截器(日志、鉴权、重试策略)、错误模型、解析与版本协商。
体验 :请求合并、缓存策略、离线队列(若需要)、弱网 UI 反馈。
安全:证书校验、敏感信息不落日志、混淆与反调试按合规要求。
5.2 界面与导航
导航作为一等公民 :深链接、登录拦截、栈管理、多 Tab 与模块化路由要有一致规则。
状态管理 :无论 MVVM 还是 MVI,关键是单向可追溯与可测试;避免"双向绑定到处飞"导致状态来源不清。
5.3 本地持久化
明确 :缓存(可丢) vs 源数据(不可随意丢) vs 配置。
读写路径尽量经 Repository;迁移策略与版本号要有规范。
5.4 动态化与发布节奏
配置驱动、远程开关、资源下发(注意审核政策与隐私)。
热修复在不同平台与商店政策下差异极大,应作为风险与合规决策,而不是纯技术炫技。
六、平台视角:iOS 与 Android 的共性差异
| 点 | iOS | Android |
|---|---|---|
| UI 声明式趋势 | SwiftUI | Jetpack Compose |
| 并发 | Swift 并发 / GCD | Kotlin 协程 |
| 模块化 | SPM / XCFramework / 私有 Pod | Gradle 模块 / AAR |
| 系统约束 | 后台、推送、隐私弹窗更"严格且统一" | 厂商差异、后台限制碎片化 |
架构思想可以共用:边界、依赖方向、测试策略;实现选用各自生态内成熟组件即可。
七、几条补充
模块化与构建速度 :细粒度模块 + 明确依赖,有助于并行开发与增量编译;这与"不要巨型 Common "同一逻辑。
大仓 / 多仓 :取舍在协作成本与工具链;关键是接口契约与版本策略清晰。
跨端复用 :Kotlin Multiplatform、共享网络模型等可降低成本,但要警惕为了复用而扭曲边界------共享层应稳定、薄,而不是把整个 App 逻辑塞进 shared。
可观测性 :崩溃、性能、关键业务漏斗应纳入架构基座,否则"架构"只剩目录结构。
八、结语
移动端架构的本质,不是选一个时髦缩写(MVI、Clean 等),而是:在快速迭代的产品节奏下,用清晰的模块与一致的规范,降低协作与演进成本。