Administrator
发布于 2026-04-30 / 2 阅读
0
0

热插拔任务流架构

你的电商项目不应该是:

页面 → 固定 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 是装配和状态中心。


评论