iOS组件化的一点心得

为什么要选择组件化

        随着项目业务不断扩展,原来的单project方式给我们的维护和扩展工作愈发困难,维护方面:我们如果需要去项目里找一个功能模块的viewController除了搜索以外,似乎只能通过文件目录的逐层查找了;业务扩展方面:如果公司另外的APP需要引用已有项目的某个功能模块,这个时候我们似乎又只能采取copy代码的方式了。这显然不是我们希望出现的工作方式。
显然组件化是化解上面困难点的优雅方式,通过一段时间的使用和阅读一些知名博客的总结,总结了组件化的一些优缺点:

优点:
  • 简化了代码整体结构,降低了维护成本。
  • 为代码和模块的复用提供了基础。
  • 对不同的业务模块可以进行物理隔离(通过git 仓库权限控制),进一步提升代码的稳定性和安全性。
  • 极大地提升了整体架构的伸缩性,为将来的业务扩展打下了基础。
  • 更好的分工协作,团队会安排团队成员各自维护一个相对独立的业务组件
  • 单独的业务组件可以直接提交给测试使用
  • 代码冲突的问题会变得很少
缺点
  • 前期维护比较麻烦,对于前期功能尚未稳定的时候,修改、更新组件频率较高,比较费时。没有单Project的方便快捷。
  • 入门门槛较高,新手入门需要的成本也更高
  • 工具的使用成本,团队间和模块间的配合成本升高,开发效率短期会降低。

设计原则

组件化本身就是软件设计基本原则的体现,这里简要从几个方面阐述组件化怎样体现,怎么操作才能更好地遵循软件设计的原则。

高类聚

这里说的就是我们拆分组件粒度大小的原则了,什么样的功能模块才适合作为一个组件,如果一个功能模块只做一件或者一类事情,那么他就符合拆分成组件的基本要求了,即满足高类聚的要求了。

低耦合
组件分层

合理划分组件之后,我们发现组件之间难免是会存在依赖关系的,我们如何减少组件之间的依赖呢?这里是我们先对组件进行分层。常见的分层结构为基础层核心层业务层,我们分层的目的是为了更好遵循依赖倒置原则,所谓依赖倒置原则为:

  • 越底层的模块,应该越稳定,越抽象,越具有高复用度。

换言之就是我们基础层需要具有稳定性、可复用性,原因显而易见,只有稳定的基础设施才能孕育出健壮的程序。
底层组件不要依赖高层的组件,同一层的组件之间应该减少依赖。这里的分层是一个抽象的概念,需要开发者根据经验和实际需求对组件进行分层。


分层结构

除了引入分层来划分组件之间的界线以外,我们会发现通常业务组件之间都存在或多或少的依赖关系,这里我们举例商城应用里,我们将商品详情和店铺详情各自抽离成一个组件,业务上难免会有相互依赖的时候,这个时候我们就得有一套组件之间通信的方案,常见的解决方案有target-actionprotocol方案,这里我们选择的是target-action,具体的实施方案会在下面通信主题里讲到。

关于category的使用
开放封闭原则
- 对扩展开放,对更改封闭。
- 类模块应该是可扩展的,但是不可修改。

不止是组件封装的时候,任何时候我们都应该遵循如此原则。根据这个原则,在面对新的需求时,我们应该尽可能地避免去更改底层组件结构,而选择去扩展。在开发中里我们一般怎么遵循此原则呢?

  - 对于外界不关心的方法和属性不要暴露,对于部分属性尽可能对其读写属性进行描述。
  - 尽可能对可能出现的业务更改留下扩展接口。比如当前需求让我们封装在一个加载文字的视图,这里我应该考虑到该视图在未来是否有可能会加载富文本或者加载图片。

通信

我在项目中使用的方案是target-action,使用的工具是casa 大神的CTMediatorCTMediator 的核心思路就是:通过target找到对应的类,再通过action找到对应的方法,在这里作为一个基础组件就可以使得业务组件之间的解耦。举个例子:
下面有两个组件:搜索列表组件和商品详情组件。
搜索列表点击列表上的商品会跳转到商品详情,于是搜索列表的组件就有以下代码:

- (void)collectionView:(UICollectionView *)collectionView didSelectItemAtIndexPath:(NSIndexPath *)indexPath { 
    UIViewController *viewController = [[CTMediator sharedInstance] performTarget:@"MJGoodsDetail" action:@"goodsDetail" params:@{
        @"articleId":articleId} shouldCacheTarget:NO];
   [self.navigationController pushViewController:viewController animated:YES];
}

在商品详情组件会去实现一个Target_MJGoodsDetail的类和Action_goodsDetail方法。

@implementation Target_MJGoodsDetail
- (id)Action_goodsDetail:(NSDictionary *)params {
    NSString * articleId = [params objectForKey:@"articleId"];
    MJGoodsDetailViewController *goodsDetailViewController = [[MJGoodsDetailViewController alloc] init];
    goodsDetailViewController.articleId = articleId;
    return goodsDetailViewController;
}
@end

更详细的介绍请到:https://github.com/casatwy/CTMediator
在使用CTMediator的过程中,需要考虑到路由文件的归宿问题,我在这里是将路由分为了面向组件和面向APP,所谓的面向组件的路由即组件自身将开放给外部使用的功能的标识,面向APP的路由即APP提供给外部(三方APP、H5)使用的功能的标识,面向组件的路由应由组件自身维护,而面向APP的路由则由主项目维护。所以常见的组件项目的目录结构为:

| -- Pods
     | -- projectName
          | -- API
          | -- Router
               | -- target_targetName.h
               | -- target_targetName.m
          | -- Controller
          | -- View
          | -- Model

组件拆分

一个项目可以完全在一个xcodeproj里通过文件夹的方式来拆分组件,但是这种低效的方式显然不符合我们的要求,相信大部分iOS开发者都会使用cocoapods来集成三方的库,深入了解cocoapods之后会发现,这简直就是为组件化量身定制的,cocoapods所做的工作一是完成组件自身的依赖管理,二是方便主项目管理组件。关于cocoapods的使用可以查看:https://www.jianshu.com/p/069e91b9f8d5

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

推荐阅读更多精彩内容