返回文章列表

Swift Package Manager 系列 07|我会怎样用 SPM 管理一个中型 iOS 项目

中型项目真正怕的不是模块不够多,而是模块存在了却没有稳定的依赖方向和职责边界

如果让我用 SPM 管一个中型 iOS 项目,我最先关注的不会是“拆多少个 Package”,而是这三个问题:

  • 哪些能力真的值得独立
  • 模块依赖怎么保持稳定方向
  • 宿主工程到底该保留什么,不该保留什么

因为中型项目最容易掉进一个陷阱:
看起来已经开始模块化了,但实际上只是把原来主工程里的复杂度重新分布到了多个 Package。

所以这篇文章我更想讲的不是“推荐拆成几个模块”,而是我会怎样判断模块、层次和依赖图。

一、我不会一开始就追求“模块多”,而会先追求“层次清楚”

中型项目的复杂度通常还没大到必须极致细分,但已经足以让“全部堆在主工程里”开始变得危险。

这时候最重要的不是拆得多,而是先拆出层次感。

我通常会先看项目里能不能稳定分出下面几类东西:

  • 基础能力层
  • 领域能力层
  • UI 复用层
  • 宿主工程层

这四类东西一旦混在一起,项目规模一上来就很容易失控。
但如果层次先立住了,模块数量反而是后面的细节。

二、我会先分三类最核心的模块

1. 基础能力模块

例如:

  • 网络
  • 日志
  • 缓存
  • 配置读取
  • 基础工具

这类模块的特点是离业务远、复用性强、依赖方向应该尽量向下封闭。

2. 领域能力模块

例如:

  • 账号
  • 用户
  • 内容
  • 订单

这些模块不是页面,而是业务能力中心。
它们应该承载领域模型、仓库、用例,而不是具体页面实现。

3. UI 复用模块

例如:

  • 设计系统
  • 通用组件
  • 通用列表容器

这里我会很谨慎,避免把业务页面误拆成 UI 模块。
UI 复用模块更适合承载稳定、通用、跨页面的组件能力。

三、宿主工程应该保留什么

这是很多团队容易忽略的问题。

一旦开始做 SPM,很容易出现一种倾向:
“既然都模块化了,那宿主工程最好越薄越好。”

这句话只对一半。

宿主工程确实不该承载太多可复用能力,但它仍然应该保留一些天然属于宿主的东西,比如:

  • App 生命周期编排
  • 路由装配
  • 环境配置注入
  • 模块组装
  • 最终产品形态相关代码

也就是说,宿主工程不是“什么都不放”,而是应该专注在装配和产品级协作上,而不是承载一堆本可下沉的能力。

四、我不会一开始就拆太细

这是我非常坚持的一条。

中型项目最容易掉进的坑之一,就是“为了模块化而模块化”,最后把系统拆得过碎。

模块一旦过碎,问题会立刻出现:

  • 依赖图复杂
  • 调试路径变长
  • review 时跨模块跳转频繁
  • 一点点改动就涉及多个包联动

这会让团队很快开始怀疑模块化本身。

所以我更倾向于:

  • 先拆出少数职责清楚的大模块
  • 观察几个迭代
  • 再决定是否细化

第一次就把系统切得很细,通常不是成熟,而是着急。

五、依赖方向比模块数量更重要

如果让我在“多拆几个模块”和“把依赖方向理顺”之间选一个,我一定选后者。

因为模块多并不自动等于结构好。
真正决定系统能不能长期稳定演进的,是依赖方向是否清楚。

例如我更在意这些关系是否成立:

  • 基础层不依赖业务层
  • 领域层不反向依赖宿主层
  • UI 复用层不偷带页面业务语义
  • 宿主层负责装配,而不是把内部实现全都攥在手里

只要依赖方向乱了,模块再多,系统也只是在“多层嵌套的耦合”。

六、我会很警惕“万能公共模块”

这是中型项目里高频出现的反模式。

项目一开始做模块化时,经常会出现一个叫:

  • Common
  • Shared
  • Core
  • Base

之类的超级模块。

如果这个模块承载的是明确基础能力,那没问题。
但很多项目里的“公共模块”最后会慢慢变成:

  • 哪儿都能依赖
  • 什么都往里放
  • 既有工具函数,又有业务模型,又有 UI 组件

结果就是它反而成了新的中心耦合点。

所以我更愿意拆成职责明确的小基础模块,而不是造一个什么都兜底的大公共模块。

七、中型项目模块化最重要的不是技术,而是团队认知一致

这点非常现实。

中型项目里,很多结构问题不是工具不行,而是团队对边界没有一致理解。
例如有人觉得:

  • 页面相关都算一个模块

有人觉得:

  • 领域模型应该单独拆

有人觉得:

  • 公共组件应该跟业务模块放一起更方便

如果这些认知长期不统一,那么你即使用了 SPM,系统也会不断长出边界冲突。

所以在中型项目里,我会很重视:

  • 模块职责的命名是否一致
  • 依赖方向是否有共识
  • 新增代码时大家能不能判断应该放哪一层

这比单纯“拆出了多少包”重要得多。

八、结论:用 SPM 管中型项目,核心不在数量,而在依赖图是否长期稳定

如果只用一句话总结,我会说:

用 SPM 管理一个中型 iOS 项目,最重要的不是拆出多少个 Package,而是让基础能力、领域能力、UI 复用和宿主装配之间形成长期稳定的依赖方向。

做到这一点,模块数量自然会找到合适规模。
做不到这一点,拆再多也只是把复杂度重新切片。