Feed架构分层技术方案

20 阅读2分钟

一、数据流架构图

mermaid-1782294653285.png

分层定义与职责边界

  • UI 层(View / Controller / Cell)

    • 位置: ViewController.swift 、 DemoUI.swift 中的 FeedPostCell 、发布页 VC 等
    • 职责:
      • 管理 UIKit 生命周期、布局、交互(按钮、列表、prefetch)
      • 将用户事件转交给 VM(如 refresh() 、 loadNextPageIfNeeded )
      • 订阅 VM 输出(closure / delegate),驱动 UI 更新
    • 禁止:
      • 直接创建网络/持久实现( MockFeedAPI() / SQLitePostStore() )
      • 直接访问全局单例( FeatureFlagCenter.shared 等),除非是组合根注入后的引用
  • VM 业务层(ViewModel)

    • 位置:建议集中到 DemoModelsAndInfra.swift (或后续拆分到 Feed/ 、 Publish/ 目录)
    • 职责:
      • 业务编排:分页、弱网降级、限流、缓存读取/写入策略
      • 输出 View 所需的最小状态(posts、loading、error message)
      • 仅依赖协议: FeedAPI 、 PostStoring 、 NetworkMonitoring 、 FeatureFlagProviding
    • 禁止:
      • 引用 UIKit 类型(除非是图片等确有必要;FeedVM 当前已不依赖 ImageLoader)
      • 直接写 UI(alert、label.text)
  • 网络层(API / Service)

    • 位置: DemoModelsAndInfra.swift (已有 FeedAPI/MockFeedAPI )、发布的 JPEGUploading/UploadService
    • 职责:
      • 请求、解析、错误封装
      • 提供稳定协议接口给 VM: FeedAPI , JPEGUploading
    • 约束:
      • 不依赖 UI,不依赖数据库
  • 持久层(Store / DB)

    • 位置: DemoStorage.swift ( SQLitePostStore )
    • 职责:
      • 数据读写、迁移、线程安全封装
      • 对外通过协议暴露: PostStoring
    • 约束:
      • 不知道页面、不知道分页策略(策略属于 VM)
  • 基础设施层(Infra)

    • 位置: DemoImages.swift ( ImageLoader: ImageLoading 、 ImageCompressor: JPEGCompressing )、 DemoModelsAndInfra.swift (FeatureFlag、NetworkMonitor、Analytics、RateLimiter)
    • 职责:
      • 提供跨业务可复用能力(缓存、监控、埋点、限流、图片加载)
      • 对外用协议抽象,业务层通过注入使用

依赖关系规则(强约束)

  • 允许依赖方向(上层依赖下层的抽象):
    • UI → VM(具体 VM 类型或协议均可)
    • VM → 协议(Network/Persistence/Infra 的 protocol)
    • Infra/Network/Persistence → Foundation/系统库
  • 禁止反向依赖:
    • Network/Persistence/Infra 不得 import UIKit(图片除外已在 DemoImages.swift)
    • VM 不得依赖 UI 组件(UIViewController/UILabel/UITableView 等)
  • 组合根唯一入口:
    • SceneDelegate 负责创建“具体实现”,并注入到 VC/VM(Composition Root)

基于 ViewController.swift 的落地设计

1) ViewController 的依赖注入(已落地)

  • 当前 ViewController 已按分层方案注入:
    • FeedViewModel (VM)
    • ImageLoading (infra)
    • FeatureFlagProviding (infra)
    • AnalyticsTracking (infra)
  • 价值:
    • UI 层不再负责组装依赖;可在测试中注入 fake/mock

2) UI 与 VM 的通讯机制

  • VM → UI:closure 回调(当前已有)

    • onStateChanged :驱动 table reload
    • onError :UI 展示 alert
  • UI → VM:直接调用 async 方法(当前已有)

    • loadInitial/refresh/loadNextPageIfNeeded 建议规范化:
  • VM 输出尽量不直接暴露整个 VM(当前 onStateChanged: (FeedViewModel)->Void ),改成输出结构化 State (降低 UI 对 VM 内部字段耦合)。

  • UI 的刷新与分页触发由 UI 控制,业务节流/降级由 VM 控制。

3) Cell 与业务的边界

  • FeedPostCell.configure 依赖:
    • ImageLoading :拉图/取消
    • AnalyticsTracking :曝光/加载成功失败埋点
  • 这样 Cell 不需要知道 ImageLoader.shared 或 AnalyticsTracker.shared

Demo: Github