首先明确一下 项目架构 非 设计模式。在我看来,MVVM,MVP,Reactive,Reactor…这些都只能算是某个功能点的设计,而难以称得上项目架构
项目架构
先看几个项目的架构:
提炼
有了例子之后,理解起来应该就会好很多了。对比非常经典的 TCP/IP 5层模型,我们的 APP 会划分如下:
层 | 组件 | 组件 | 组件 | 组件 | 组件 |
---|---|---|---|---|---|
应用 | App | … | |||
业务 | 登录 | 分享业务 | 回答页、问题页、个人页 | 项目WebKit | … |
服务(应用) | 项目UI风格 | 统计 | 用户数据库、缓存数据 | 服务 | … |
服务(基础) | 设备信息 | 基础统计、catch 统计 | 基类 和 Aop | Log(request、page、action) | … |
库(三方) | Net | Rx | UI(PopView,Alert,Sheet) | WebKit | … |
库(Cocoa) | 扩展 | 封装 | 语法糖 | 便利 | … |
申明一下组件化的核心是: 每一层只依赖下一层, 同一层之间解耦
在这个 Protocol 下, 每一个组件在接口不改变的情况下只需要 替换组件即可完成功能上的迭代,如果接口改变了也只需要上层使用的模块做对应的更新修改即可。
解释一下 ,为什么把服务分为2层:
-
首先,服务和业务是一个分界点,毋庸置疑,之所以没有用“组件”这个名字,是因为觉得服务更加贴切,符合后边描述对应的内容
-
服务分为应用和基础两个方面,那么开发新的系统时候就会很明确:基础服务 应当 不需要改动 就可以在其上开发其他应用。应用服务 需要的是 修改类 ,即可适配 新的系统。
有了这个基本架构图就可以进行编码设计了
具体实施
如果有些不明白的可以看一下上一篇: Swift组件化方案探究和实践 ,了解一下项目整体采用的方案,主工程和组件工程之间的关系。
模块实施
自下而上实施如下:
- 库 :应当将 库(三方) 和 库(Cocoa) 放于一个 repo 下,此项目不包含任何其他业务代码(纯粹扩展系统功能),相当于一个基础 framework 库,按照版本更新。具体就是包含 pod 和一些对应的扩展,部分分类亦可用于实现第三方接口发生变化时候更新三方库单维持原接口。(此部分API应稳定,故放置统一 repo)。
- 服务(基础) : 将基础服务分别创建 repo,单独管理升级,将项目冠以 base 前缀。不应当依赖主工程,应当只依赖下层,即: 库
- 服务(应用) : 分别创建 repo,单独管理升级,项目冠以 project 前缀。不应当依赖主工程,应当只依赖下层,即: 库
- 业务 : 根据情况依赖某些服务,分别创建 repo,项目冠以 module 前缀。不应当依赖主工程,应当只依赖下层,即: 服务
- 应用 : 主工程按需导入相应的应用,设置主框架,灵活插入组件即可实现应用更新迭代。
注意点
主工程作为一个特殊的工程程,按需豁免,可以依赖底层库(待商榷)。
组件不应当依赖主工程,应当只依赖下层
版本号命名: 基础组件tag版本号第一个跟 base 组件相同,例如 base 基于于 swift 4.0,版本号 1+,依赖 base 的各个组件版本号应当同为1+,当更新为 swift 4.2 时候, 版本号应当为2+,组件版本应同为2+
结语
在此项目框架和组件化的要求之下,业务和组件分别依赖底层,相互直接不产生依赖,项目更加清晰明了,易于维护,测试和扩展。