跨端架构设计模式深度解析
跨端架构模式:MVVM、Redux/Bloc、Clean Architecture 与模块化在跨端项目的落地。 讲清各模式职责划分,掌握后能答出「大型跨端 App 怎么分层」。
一句话概括
跨端架构的核心不是选哪个库,而是解决”状态从哪里来、往哪里去、谁来通知 UI”这个三角问题——理解了状态流转路径,BLoC/Riverpod/Redux 都只是这个路径的不同实现。
核心知识点
1. 状态管理的本质:三个角色一场戏
1
2
3
4
5
6
7
8
// 任何一个状态管理方案都在回答三个问题:
// ① 谁持有状态?(Store / Notifier / Bloc)
// ② 怎么变状态?(dispatch / emit / state = newState)
// ③ 谁通知 UI 刷新?(Consumer / BlocBuilder / useSelector)
// 这个模式比你想象的要简单:
// 用户操作 → 发送意图 → 产出新状态 → UI 自动响应
// 不同框架只是这三个环节的语法糖不同
2. Clean Architecture 为何在跨端特别重要
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
// 核心原则:业务逻辑中不能出现一行 Flutter/RN 的 import
// ❌ 反过来就错了——UI 层可以依赖业务层,业务层绝不能依赖 UI 层
// Domain 层:纯 Dart/TS,不 import 任何框架
abstract class OrderRepository {
Future<Order> create(Cart cart, Address addr);
}
class CheckoutUseCase {
final OrderRepository repo;
CheckoutUseCase(this.repo);
Future<CheckoutResult> execute(Cart cart) async {
// 库存检查 → 支付 → 创建订单,纯业务逻辑
// 这段代码可以在任何框架里跑,单元测试一行 mock 就够
}
}
3. 三层对比:RN vs Flutter vs ArkUI 的架构偏好
1
2
3
4
5
6
7
8
9
10
11
// RN:社区野蛮生长,没有官方推荐
// → Redux Toolkit / Zustand / Jotai 三足鼎立
// → 选 Redux 的原因通常是"团队会",不是"项目需要"
// Flutter:Google 刻意模糊标准答案
// → BLoC 曾被视为正统,但 Riverpod 已经追平甚至超过
// → 选 BLoC 的理由:事件可追溯 + 大团队强制规范
// → 选 Riverpod 的理由:更少模板代码 + AsyncValue 天然支持 loading/error/data
// ArkUI:华为提供 @State/@Provide/@Consume 装饰器
// → 适合中小型应用,大型项目仍需要引入类似 MVVM 的分层
4. 模块化:”按功能分层”而不是”按类型分包”
1
2
3
4
5
6
7
8
9
10
11
12
13
14
// ❌ 初学者最爱(按类型):
components/ ← 100 个组件扔一起
screens/ ← 50 个页面扔一起
services/ ← 30 个 service 扔一起
// ✅ 正确姿势(按功能):
features/auth/ ← 登录注册的全部东西在这
├── domain/ ← entities + usecases
├── data/ ← repositories + datasources
└── presentation/ ← pages + widgets + providers
features/feed/
features/chat/
// 核心判断:删掉一个功能时,只删一个目录就行
5. 平台适配:策略模式,不是 if-else 堆砌
1
2
3
4
5
6
7
8
9
10
11
// ❌ 散落各处的 Platform.isIOS 判断
if (Platform.isIOS) { /* 10 行 */ }
if (Platform.isAndroid) { /* 8 行 */ }
// ✅ 统一 adapter 层 + 策略模式
abstract class PlatformNavigator {
void openSettings();
}
class IOSNavigator implements PlatformNavigator { ... }
class AndroidNavigator implements PlatformNavigator { ... }
// 全项目只有一个地方决定用哪个实现
其实你每天都在用
- React Navigation 的 push/pop:背后是原生 UINavigationController / FragmentManager 的桥接调用,不是你 JS 线程里的操作
- **Provider.of
(context)**:本质是 Flutter 的 InheritedWidget,沿着 Element 树往上找,找到最近的那个类型——跟 React Context 一个思路 - Redux 的 reducer:跟 Array.reduce 完全一样的模式,
(prevState, action) => nextState,只是加了订阅机制 - get_it 依赖注入:一个全局 Map<Type, Object>,注册时放进去,用时取出来——Service Locator 模式,简单粗暴但有效
- ArkUI 的 @Consume:跟 Flutter 的 InheritedWidget 几乎一样的思路,祖先提供数据、后代订阅消费,不需要 props 逐层透传
常见误解(FAQ)
❌ 误区一:”状态管理选错了,项目就完了”
这是一个被过度贩卖的焦虑。实际上,只要你把业务逻辑从 UI 中抽离(哪怕只是一个简单的分离),后续换方案的成本并不高。Redux → Zustand、BLoC → Riverpod 的迁移通常只需要改 Provider 声明和 UI 消费方式,Domain 层完全不动。关键是分层,不是选库。
❌ 误区二:”Clean Architecture 能让代码自动变好”
Clean Architecture 只是结构约束,不是质量保证。如果 UseCase 里写满了 await Future.delayed() 等假逻辑、Entity 只是一个 map 的包装、Data 层的错误处理全是 catch(e) { return null }……那 Clean Architecture 只是把烂代码搬到了更深的目录里。
❌ 误区三:”Redux 性能差,不要用”
Redux 本身不慢——selector 机制配合 shallowEqual 可以精准控制 rerender 范围。让人感觉慢的通常是:① 把整个 App 状态塞一个 reducer 里;② 没用 createEntityAdapter 管理列表;③ selector 里做了昂贵的计算而不是用 createSelector 缓存。
❌ 误区四:”ArkUI 太新了,架构不成熟”
ArkUI 的 @State/@Link/@Provide/@Consume 装饰器体系其实借鉴了 SwiftUI 和 Compose 的声明式 UI 思想。它在响应式粒度上的设计比 RN 的 setState 更先进。真正不成熟的是社区生态(第三方架构库少),不是框架本身。
一句话总结
跨端架构的精髓不在于”用哪种模式最好”,而在于变化发生时,你需要改多少代码——好的架构让变化只触及边界,差的架构让变化传播到全项目。