你的电商项目不应该是:
页面 → 固定 Manager → 固定 Service → 固定 API而应该是:
页面 → TaskFlow → Manager Protocol → Service Plugin → DataSource Plugin核心目标是:
可替换
可组合
可降级
可 Mock
可灰度
可按任务流执行推荐最终形态
Feature Page
↓
ViewModel / Riverpod Notifier
↓
TaskFlow / UseCase
↓
Manager Protocol
↓
Service Plugin
↓
DTO / Mapper / Model
↓
API / Cache / Mock / Local也就是说,页面不直接依赖某个具体 Manager。
页面只发出任务:
LoadHomeTask()
AddCartTask(productId)
CreateOrderTask()
PayOrderTask()任务再决定调用哪个 Manager、哪个 Service、哪个数据源。
Manager 也不能写死
不要这样:
final cartManager = CartManager(CartApiService());而应该这样:
abstract class CartService {
Future<CartModel> getCart();
Future<void> addCart(AddCartDTO dto);
}
final cartServiceProvider = Provider<CartService>((ref) {
final env = ref.watch(appEnvironmentProvider);
if (env.useMock) {
return MockCartService();
}
return ReleaseCartService(ref.watch(networkClientProvider));
});Manager 只依赖协议:
class CartManager {
CartManager(this.service);
final CartService service;
Future<CartModel> loadCart() {
return service.getCart();
}
}Provider 决定注入什么:
final cartManagerProvider = Provider<CartManager>((ref) {
return CartManager(
ref.watch(cartServiceProvider),
);
});这样以后你要换:
Dio → HttpClient
真实 API → Mock
REST → GraphQL
本地缓存 → 远程接口
旧支付 → 新支付 SDK页面完全不用动。
任务流应该是核心
比如加购不应该只是:
cartManager.addCart()而应该是一个完整 TaskFlow:
AddCartFlow
1. 检查登录
2. 检查商品状态
3. 检查 SKU
4. 调用购物车服务
5. 刷新购物车角标
6. 记录埋点
7. 显示成功提示代码结构类似:
class AddCartFlow {
AddCartFlow({
required this.authManager,
required this.cartManager,
required this.analyticsManager,
});
final AuthManager authManager;
final CartManager cartManager;
final AnalyticsManager analyticsManager;
Future<void> execute(AddCartInput input) async {
if (!authManager.isLoggedIn) {
throw NeedLoginException();
}
await cartManager.addCart(input);
analyticsManager.track('add_cart', {
'productId': input.productId,
'skuId': input.skuId,
});
}
}Riverpod 注入:
final addCartFlowProvider = Provider<AddCartFlow>((ref) {
return AddCartFlow(
authManager: ref.watch(authManagerProvider),
cartManager: ref.watch(cartManagerProvider),
analyticsManager: ref.watch(analyticsManagerProvider),
);
});页面只调用:
await ref.read(addCartFlowProvider).execute(input);这就非常接近你之前 AIChats 的思想了。
我建议你最终分成 5 层
1. Plugin Layer
DioService / MockService / FirebaseService / LocalService
2. Manager Layer
AuthManager / CartManager / OrderManager / PaymentManager
3. TaskFlow Layer
LoginFlow / AddCartFlow / CreateOrderFlow / PayOrderFlow
4. State Layer
Riverpod Notifier / AsyncNotifier / ViewModel
5. UI Layer
Page / Section / Component / Cell项目目录可以这样
lib/
├── core/
│ ├── plugin/
│ ├── manager/
│ ├── task_flow/
│ ├── network/
│ ├── cache/
│ ├── di/
│ └── model/
│
├── features/
│ ├── home/
│ ├── product/
│ ├── cart/
│ ├── order/
│ ├── payment/
│ └── user/每个业务模块内部:
features/cart/
├── data/
│ ├── dto/
│ ├── mapper/
│ ├── service/
│ │ ├── cart_service.dart
│ │ ├── release_cart_service.dart
│ │ └── mock_cart_service.dart
│ └── model/
│
├── domain/
│ ├── cart_manager.dart
│ ├── cart_flow.dart
│ └── cart_repository.dart
│
├── presentation/
│ ├── cart_page.dart
│ ├── cart_view_model.dart
│ ├── cart_state.dart
│ └── widgets/最终开发规则
我建议你定成这几条铁律:
1. Page 不直接调用 Service
2. Page 不直接调用 Dio
3. Page 不直接解析 DTO
4. Manager 不依赖具体 ReleaseService
5. Flow 负责串联多个 Manager
6. Provider 负责装配依赖
7. Mock 和 Release 必须实现同一个协议
8. DTO 只表示接口数据
9. Model 只表示业务可用数据
10. UI 只使用 Model,不碰 DTO你的项目核心架构可以命名为
Pluggable TaskFlow Architecture中文可以叫:
热插拔任务流架构它特别适合你的目标:
电商平台
多环境
多接口来源
Mock/Release切换
快速换 API
快速换支付
快速换缓存
快速换 UI 组件
AI 按任务生成代码我觉得你现在这个方向是对的。
Manager 是能力中心,TaskFlow 是业务流程中心,Riverpod 是装配和状态中心。