iOS 组件化实现的一些思路总结

组件化

背景

大概在一个月之前,公司有一个需求需要出一个功能和业务逻辑和当前应用相同的新版本,所有的UI重新设置过而不止是配色字体图标等信息的简单修改。因为当时排期相对的不太紧,所有决定把整个项目做一个重构,为了实现更好的重构,发了点时间看了大概30多篇关于组件化的博客和文章,也会把这些文章的链接贴在底部,然后动手开工了,今天有时间把这次重构过程中的一些想法总结下。

本文主要涉及到以下几个主题:

  • 组件化遵循的原则
  • 组件化分层模型
  • 组件化集成方法

遵循原则

设计中提到的SOLID在组件化的过程n

  • 高层依赖底层,下层不能对上层有依赖的关系
    这点是基本的设计原则,可以通过依赖倒置(依赖反转原则DIP)来设计。

  • 插件的设计方便扩展
    这点是符合开闭原则(开闭原则OCP),

  • 同层级的模块不依赖或者尽量少依赖
    这点同时也是基本的设计原则,可以通过控制反转(接口隔离原则ISP)来设计,典型的就是使用观察者模式来实现同一个层级模块的解耦。

  • 最小知识原则和自完备性
    一个独立的模块尽量减少对其他低层模块的依赖,比如一个模块只是依赖低层模块的某个类的方法,不妨把这个方法拷贝到此模块中,如此一来这个模块就具有了更好的自完备性。这也是符合单一职责原则的(单一职责原则SRP)。

分层结构

分层模块图2

图片来源:58 同城 iOS 客户端组件化演变历程
以上图来自网络,基本上可表述了组件化设计和实现的思路。

Ⅰ. 基础底层组件
稳定的、和业务无关的组件,这一层就是传说中的技术组件,这些组件在每个应用中基本都会存在,包含了:

  • 封装基础的网络操作
  • 数据库
  • 日志
  • 工具类:常用分类、宏定义
  • 基础UI组件
  • 缓存管理模块
  • 其他第三方组件

底层组件-基础网络库

根据输入输出的思想进行封装,封装变化

不封装的不变的部分:

  • 输入参数中不变的HttpHeader
  • http层缓存的处理
  • 二进制数据转换为JSON格式

输入变化的部分包含:

  • url
  • 参数
  • 数据类型
  • 其他参数

输出变化的部分包含了:

  • 回调(JSON数据,错误码,错误信息)
  • 全局的错误处理(发送请求无网络处理,URL加载系统出错的处理,业务错误的处理(授权失败))

其中输入输出部分有的是可选的,除了定义一个全能的外部接口,需要提供若干个简便外部接口提供个客户端使用:

客户端使用的是简单的请求,只需要调用简单外部接口传递 url参数 而不需要传递
数据类型其他参数数据类型其他参数 这两个参数使用默认值即可。

客户端关系返回数据的错误码或者错误信息,定义一个只包含错误码,错误信息回调的简单接口即可,而不传递JSON数据。

提供给上层的网络请求接口是不变的,用户无需关心网络底层的具体逻辑实现,网络请求底层可以使用系统的URL加载系统,或者使用第三方的封装不会到客户端造成影响。

底层组件-工具类和常用宏

宏定义的分类

字符串处理相关

  • 字符串的空处理
  • 国际化格式字符串宏

对象处理相关

  • 对象模型序列化相关宏
  • 对象的单例宏

设备信息宏:

  • 屏幕的尺寸、Tabbar高度、NavBar高度等宏
  • ios版本宏
  • iPad or iPhone 判断宏

DEBUG宏

  • 自定义的Log宏定义

颜色宏定义

  • 十进制RGB格式的颜色
  • 十六进制HEX格式的颜色

宏定义处理注意点

宏定义避免和具体的类有互相依赖的关系
eg.
UtilMacro -> UIUtil -> UtilMacro

宏定义有间接的依赖
eg.
ProductParameter -> UtilMacro -> UIUtil

常用的Category

  • UI系列:UIXXX-Category
    UIView/UIColor/UIImage/UILabel/UIImageView/UIViewController
  • NS系列:NSXXX-Category
    NSDate/NSObject/NSData/NSString/NSDictionary

底层组件-数据库模块

数据库的使用在应用中很常见,主要需要实现以下功能:

  • 数据库管理者提供外部访问数据库的接口
  • 数据库管理者拥有包含但是不限于数据库自动版本升级处理的功能

具体可以参考iOS 数据库升级数据迁移解决方案

底层组件-基础UI组件

基础的UI组件适用于所有的业务场景的并且支持扩展的UI组件,业务的变化,基础UI组件不能有改动但是可以进行扩展和定制,常用的主要有以下:

  • 上下拉刷新组件
  • 轮播组件
  • HUD提示组件
  • 滑动返回组件
  • 分页组件
  • 自定义Tab组件

底层组件-缓存管理模块

缓存管理有很多的应用场景,比如缓存页面列表、详情页的数据,提高加载数据以达到优化用户体验,需要关注以下几个方面:

  • 缓存存储策略 缓存数据保存的位置以及缓存保存的名称
  • 缓存存储方式 对象归档存储,数据库存储,二进制存储,
  • 缓存的查找和取出
  • 缓存更新和过期处理
  • 提供客户端的读写接口
  • 提供客户端清除缓存的接口

Ⅱ. 基础业务层组件
相对稳定的数据提供层,数据提供包含了业务接口或者有包含了缓存读写的服务,这一层就是传说中的业务服务层组件,包含了:

  • 网络接口的封装(针对业务的,可以包含有数据的缓存读写功能)
  • IMSDK的封装层组件
  • 第三方分享、登录、支付组件
  • 统计打点组件
  • 推送通知组件

业务组件-接口的封装

接口的封装提供给上层(一般是表现层)提供数据,中心化的网络接口设计,提供的是一个模型对象给上层
更详细的网络层设计可参考:iOS应用架构谈 网络层设计方案

业务组件-第三方分享、登录、支付组件

提供第三方分享、登录、支付的服务,可以扩展自定义的第三方组件,提供以下功能

业务组件-推送通知组件

推送通知在很多业务场景中都有用到,一般滴你的产品有运营管理,推送通知是必须的功能。一个推送管理组件一般包含以下功能:

  • 在App启动时候初始化推送通知的设置
  • 处理注册Token
  • 处理接收消息
  • 提供给外部推送消息数据的接口(可以设计为观察者模式,客户端是Observer)

业务组件-统计打点组件

统计打点也是在很多app(基本所有)中有使用到的,如果没有和业务相关的打点统计、页面统计,最基本的用户新增、流程、日活等基本的数据都依赖于统计打点组件。此外一般的统计打点组件都有crash收集系统,所以这同时是一个很好的BUG反馈工具。统计打点组件一般的有以下功能:

  • 注册第三方统计平台的key,可多次注册多个平台
  • 一组统计接口提供给客户端调用

集成方法

集成方法可以选择主流的cocoapods,cocoapods提供的包管理功能十分强大,在开发阶段,可以选择开发库,即把podfile中的某个pod指向为本地podspec文件,这样方便修改。如果库完善的很好了,可以考虑把库做成私有库提交到自己的git系统以供其他项目和其他成员使用,因为篇幅限制,后续会写一篇使用cocoapods做开发库和私有库集成的文章。

使用cocoapods集成实战演练可以看我的这篇文章: iOS 组件化-使用cocoapods集成实战演练

结束

以上就是我在一次项目组件化重构中总结的一些心得,希望可以对需要的人有所帮助,不妥之处敬请指教。

参考文章链接

以下链接是来自于我的书签
iOS应用架构谈 组件化方案 - Casa Taloyum
iOS组件化方案调研 - 简书
蘑菇街 App 的组件化之路 - Limboy's HQ
做一个 App 前需要考虑的几件事 - Limboy's HQ
浅析 iOS 应用组件化设计
糯米移动组件架构演进之路 - CSDN博客
iOS应用架构谈 组件化方案 - Casa Taloyum
饿了么移动APP的架构演进 - SDK.CN - 中国领先的开发者服务平台
滴滴出行iOS客户端架构演进之路
iOS组件化思路-大神博客研读和思考 - 简书
基于 CocoaPods 和 Git 的 iOS 工程组件化实践
浅析 iOS 应用网络层设计
https://blog.cnbluebox.com/blog/2015/11/28/module-and-decoupling/
iOS组件化实践方案-LDBusMediator炼就 - 简书
使用Cocoapods创建私有podspec - GeekerProbe
cocoapods代码管理 - 刘坤的技术博客
组件化与模块化之路 - 简书
Pods依赖库快速开发入门 - 简书
CocoaPods Guides - Podspec Syntax Reference <span>v1.2.0.beta.1</span>
iOS开发——组件化及去Mode化方案 - 简书
iOS架构学习篇——组件化架构漫谈 - 简书
iOS应用架构谈 组件化方案 - 简书
Cocoapods使用私有库中遇到的坑 - 简书
大话大前端时代(一) —— Vue 与 iOS 的组件化 - 简书
Create private pods framework with Cocoapods #iOS #cocoapods · shaokanp/seekrtech_docs Wiki
手机淘宝客户端架构探索实践-博客-云栖社区-阿里云
Examples of specifications · kylefleming/CocoaPods Wiki
ios - Cocoapods dependency in pod spec not working - Stack Overflow
手机淘宝的客户端架构探索之路 - CSDN博客
微信、陌陌等著名IM软件设计架构详解 - CSDN博客
架构 白话软件设计中的六大原则 - zuochunsheng的博客 - CSDN博客
微信的软件设计使用思考 - CSDN博客
APP和服务端-架构设计(一) - CSDN博客
手机淘宝构架演化实践及优化 - CSDN博客
淘宝网技术架构介绍 - CSDN博客
App架构经验总结 - CSDN博客
IOS-组件化架构漫谈 - CSDN博客
iOS开发——组件化及去Mode化方案 - 简书
58 同城 iOS 客户端组件化演变历程-极客

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 206,126评论 6 481
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 88,254评论 2 382
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 152,445评论 0 341
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 55,185评论 1 278
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 64,178评论 5 371
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,970评论 1 284
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 38,276评论 3 399
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,927评论 0 259
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 43,400评论 1 300
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,883评论 2 323
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,997评论 1 333
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,646评论 4 322
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 39,213评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 30,204评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,423评论 1 260
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 45,423评论 2 352
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,722评论 2 345

推荐阅读更多精彩内容

  • Android 自定义View的各种姿势1 Activity的显示之ViewRootImpl详解 Activity...
    passiontim阅读 171,498评论 25 707
  • Flower Dance - DJ Okawari 行云流水的钢琴代表花的舞动。弦乐代表自由。概念极简,效果却非常...
    惟留一简书阅读 3,971评论 0 9
  • 【顾雨念南】 我们歌唱着,以迎接我们 以风的伴奏,以地的沉默 已经等不及变成轻落的雪 便带着每日蒸腾的汗水啊 重回...
    谶楷儒阅读 290评论 1 1
  • 月茫茫 花开无往 叶影墨深伤 夜凄凉 阴阴木上 两蝉泣音短长 白絮眇眇路何方 夜未央 彷而徨 何处欢歌满异乡 明月人断肠
    独孤子尘阅读 71评论 0 6