iOS 基础知识:组件化(模块化)


概念理解

组件化有什么好处?

  • 业务分层、解耦,使代码变得可维护;
  • 有效的拆分、组织日益庞大的工程代码,使工程目录变得可维护;
  • 便于各业务功能拆分、抽离,实现真正的功能复用;
  • 业务隔离,跨团队开发代码控制和版本风险控制的实现;
  • 模块化对代码的封装性、合理性都有一定的要求,提升开发同学的设计能力;
  • 在维护好各级组件的情况下,随意组合满足不同客户需求;(只需要将之前的多个业务组件模块在新的主App中进行组装即可快速迭代出下一个全新App)

如何组件化解耦的?

分层

基础功能组件:按功能分库,不涉及产品业务需求,跟库Library类似,通过良好的接口拱上层业务组件调用;不写入产品定制逻辑,通过扩展接口完成定制;

基础UI组件:各个业务模块依赖使用,但需要保持好定制扩展的设计

业务组件:业务功能间相对独立,相互间没有Model共享的依赖;业务之间的页面调用只能通过UIBus进行跳转;业务之间的逻辑Action调用只能通过服务提供;

中间件:target-action,url-block,protocol-class

为什么 CTMediator 方案优于基于 Router 的方案?

Router 的缺点

在组件化的实施过程中,注册 URL 并不是充分必要条件。组件是不需要向组件管理器注册 URL 的,注册了 URL 之后,会造成不必要的内存常驻。注册 URL 的目的其实是一个服务发现的过程,在 iOS 领域中,服务发现的方式是不需要通过主动注册的,使用 runtime 就可以了。另外,注册部分的代码的维护是一个相对麻烦的事情,每一次支持新调用时,都要去维护一次注册列表。如果有调用被弃用了,是经常会忘记删项目的。runtime 由于不存在注册过程,那就也不会产生维护的操作,维护成本就降低了。由于通过 runtime 做到了服务的自动发现,拓展调用接口的任务就仅在于各自的模块,任何一次新接口添加,新业务添加,都不必去主工程做操作,十分透明。

在 iOS 领域里,一定是组件化的中间件为 openURL 提供服务,而不是 openURL 方式为组件化提供服务。如果在给 App 实施组件化方案的过程中是基于 openURL 的方案的话,有一个致命缺陷:非常规对象(不能被字符串化到 URL 中的对象,例如 UIImage)无法参与本地组件间调度。在本地调用中使用 URL 的方式其实是不必要的,如果业务工程师在本地间调度时需要给出 URL,那么就不可避免要提供 params,在调用时要提供哪些 params 是业务工程师很容易懵逼的地方。

为了支持传递非常规参数,蘑菇街的方案采用了 protocol,这个会侵入业务。由于业务中的某个对象需要被调用,因此必须要符合某个可被调用的 protocol,然而这个 protocol 又不存在于当前业务领域,于是当前业务就不得不依赖 public Protocol。这对于将来的业务迁移是有非常大的影响的。

CTMediator 的优点

调用时,区分了本地应用调用和远程应用调用。本地应用调用为远程应用调用提供服务。

组件仅通过 Action 暴露可调用接口,模块与模块之间的接口被固化在了 Target-Action 这一层,避免了实施组件化的改造过程中,对 Business 的侵入,同时也提高了组件化接口的可维护性。

方便传递各种类型的参数。

基于 CTMediator 的组件化方案,有哪些核心组成?

CTMediator 中间件:集成就可以了

模块 Target_%@:模块的实现及提供对外的方法调用 Action_methodName,需要传参数时,都统一以 NSDictionary * 的形式传入。

CTMediator+%@ 扩展:扩展里声明了模块业务的对外接口,参数明确,这样外部调用者可以很容易理解如何调用接口。

评论