前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >组件化思考和落地

组件化思考和落地

作者头像
落影
发布2022-05-26 08:17:38
7110
发布2022-05-26 08:17:38
举报
文章被收录于专栏:落影的专栏

前言

随着我们业务发展,参与业务开发的同学也逐渐增多。为了适应新要求,需要对旧的架构做一次升级。组件化是架构升级中的重要一步,将业务模块进行组件化,将各个业务的逻辑和依赖梳理清楚,才能有效降低业务迭代带来的复杂度,为后续更复杂的优化做铺垫。

正文

问题背景

iOS的App架构早期设计分为三层:业务模块层、基础业务层、基础功能层。

业务模块层承载具体业务模块,基础业务层封装业务基础能力,基础功能层桥接依赖的Pod库。 随着业务的发展,SSCommon基础功能层接入越来越多的功能库,SSFoundation基础业务层沉淀出来BDNovelKit、BDNovelWidget、阅读器SDK和听书SDK,SSApp业务模块层也在不断生成新的功能模块。

经历多个版本的迭代,存在几个较为明显的问题: 业务模块依赖无抽象,以主Tab和分类业务模块为例,既没有主Tab要求分类业务模块实现的TabProtocol,也没有分类业务模块要求宿主实现的Delegate; 层级界限不清晰,当新增某个功能业务时,对应数据结构类型、业务组件等全部放在业务模块层; 业务模块调用不规范,比如说在书城模块需要使用其他业务模块(搜索、有声、金币)时,会直接引入的对应业务模块实例;

问题解决

组件化的目标是逻辑内聚、依赖抽象。 将复杂的工程,拆分为若干个独立的组件,将复杂的逻辑内聚,仅对外暴露接口,降低整个工程的复杂度。同时也是方便后续工程进行拆分,对于部分业务进行子仓化,部分通用的基础组件甚至可以多App复用。

通用基础层

使用范围不局限于App的基础库,既有公司提供的Heimdallr,也有自己维护的BDReader。

业务基础层

仅服务于自己业务,会被上层业务直接使用,包括SSBook这种业务基础数据结构,也有业务通用的SSBaseView,这些代码会封装到若干个Pod库。

业务接口层

业务接口层主要是描述每个业务组件的接口,调用组件应该通过接口去调用,接口层是组件生成必备。

业务实现层

业务实现层是接口层的具体实现,组件化之后的业务组件主要逻辑放在这里,实现层是组件生成必备。

主App

目前整个App大部分逻辑都是放在这里,随着组件化的推进,逐渐沉淀部分逻辑到业务实现层、业务接口层和业务基础层。

具体组件

以分类组件为例,这是分类组件的大致构成。

SSCategoryImp可以直接使用业务基础层的SSBook和SSBaseView,也可以使用通用基础层的BDALog和Heimdallr。 主App会通过SSCategoryInterface去调用分类组件,同时也会实现一个SSCategoryDelegate,作为分类部分功能的回调。

标准实现

组件内部也要分层,便于后续组件管理,以及组件间能力复用。分层建议包括组件接口层、组件实现层、组件基础层、组件数据层。 组件接口层:存放组件对外提供能力的抽象接口; 组件实现层:存放组件对接口实现的具体代码; 组件基础层:存放组件对外提供的业务UI能力;这部分复用组件较多之后,需要下沉到App的业务基础层; 组件数据层:存放组件对外提供的业务Model;这部分复用组件较多之后,需要下沉到App的业务基础层;

问题延伸
模块化

在我们的工程里,模块化指的是将业务功能模块拆分成若干个功能模块,模块可以在多个业务中复用。比如说某个书评业务使用评论组件、点赞组件、气泡组件等进行模块化编程。模块化编程可以有效提供代码的复用率,同时也便于沉淀组件。

代码分仓

直接分仓会存在增加开发成本和维护成本的问题,短期组件化会有较多改动。但是分仓又是一种比较好的物理隔离方式,可以减慢代码劣化,同时也比较方便管理依赖。待组件化成熟之后,再进行代码分仓。 业务基础层可以直接沉库,方便建立明确的层级关系。

组件通信

组件通信其实就是组件A调用组件B的某个功能,这里有几种方式,以分类组件和播放组件为例。 接口调用:分类组件有业务逻辑需要感知当前正在播放的书籍id,那么应该通过播放组件提供的抽象接口(而不是播放器实例),拿到这个书籍id; 依赖注入:分类组件描述需要依赖外部实现的能力并提供注入接口,然后外部组件再主动通过接口注入该能力的实现; 消息通知:播放组件在切换当前播放书籍时,可以通过消息通知所有关注的业务组件,业务组件Register的Message是在业务基础层;

落地规划
阶段一 基建准备

工程梳理,明确基础业务层范围,业务基础层搭建; 接口层实现和组件注册机制; 基础工具支持准备,组件调用能力;

阶段二 show case

业务落地,以某个业务做组件化,打造show case; 组件化结构合理,包括接口、数据和实现; 搭建配套的检查、review、多仓合码等机制;

阶段三 业务组件推进

降低改造成本,并逐步推广到多个业务;

组件化思考
分仓实现有哪些问题?

依赖版本管理问题,组件本身需要和主端App保持一致依赖版本号。 拆分组件之后,如果使用分仓隔离,则不能直接操作组件,需要引入多仓开发。

组件有哪些类型?

按照使用范围有: 通用组件,多端App都能用的组件; 业务组件,只有当前业务使用的组件;

按照内容区分: 功能组件,业务的具体业务组件,着重点在于逻辑内聚,代码隔离; 基础组件,业务的基础功能组件,着重点在于功能的重复利用;

业务组件由哪些组成?

代码+资源+依赖+抽象。 代码:承载具体业务逻辑的.h/.m; 资源:业务使用的图片等其他资源; 依赖:组件需要主App实现的能力; 抽象:组件提供给主App使用的能力,也就是接口层,接口层包括方法和数据类型;

业务组件的有哪些实现方式?

Development Pods,组件代码和主工程代码同仓; Pod库,类似第三方库,代码分仓; 子工程依赖,业务组件单独成为一个工程,被主工程依赖,代码同仓; 文件夹分隔,同一个主工程,用不同文件夹分隔,通过添加文件夹Reviewer来避免劣化,代码同仓;

所有的代码分仓,都需要考虑业务组件和主App的依赖版本一致问题,有些成熟业务会有业务组件容器化的解决方案,可以把业务组件和主App的pod版本对齐。 代码分仓带来了另外一个问题是工程配置、宏定义、xcconfig等不同步,需要及时打通和更新。

比较好的实践是综合上述的过程: 1、先梳理依赖,再用文件夹做简单分隔; 2、对应文件夹用Development Pods进行分隔,这一步也可以用子工程来实现;devPod相对简单,但是无法完全隔离;子工程可以物理隔离,但是维护相对麻烦; 3、Pod子仓,明确组件的subspec和podspec依赖;

业务组件如何感知App生命周期?

目前并不打算让主App对系统事件进行封装,App生命周期、Push处理、系统事件处理等由主App处理,各个组件可以直接去监听系统的事件。但有些事件只会回调到主App,那么再由主App分发事件。 待到组件化足够成熟,可以把主App再拆出若干个负责事件转发的底层组件,作为通用的依赖(容器层)。

接口层如何屏蔽具体的实例?

需要有组件的接口和绑定方法,这里用到了一个公司内部提供的库来实现,基本原理还是通过MachO段来做绑定。 组件外通过GET_PROTOCOL(SSProtocol)和GET_PROTOCOL_CLASS(SSxxProtocol) 两种方式来调用,组件内通过BIND_PROTOCOL_SERVICE(SSProtocol, SSxxImpl)来绑定接口和实现。

总结

网上关于组件化的文章非常多,这里主要介绍我们业务的思考和落地过程。 架构优化是一件持之以恒的事情,技术方案总是可以持续完善。最初的设计不用太复杂,逻辑清晰便于演进架构,能解决当下协作痛点,适应业务迭代的节奏,就是一个好的解决方案。

代码架构,合久必分,分久必合。

本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。
原始发表:2022-05-26,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 前言
  • 正文
    • 问题背景
      • 问题解决
        • 具体组件
        • 标准实现
      • 问题延伸
        • 模块化
        • 代码分仓
        • 组件通信
      • 落地规划
        • 阶段一 基建准备
        • 阶段二 show case
        • 阶段三 业务组件推进
      • 组件化思考
        • 分仓实现有哪些问题?
        • 组件有哪些类型?
        • 业务组件由哪些组成?
        • 业务组件的有哪些实现方式?
        • 业务组件如何感知App生命周期?
        • 接口层如何屏蔽具体的实例?
    • 总结
    相关产品与服务
    容器服务
    腾讯云容器服务(Tencent Kubernetes Engine, TKE)基于原生 kubernetes 提供以容器为核心的、高度可扩展的高性能容器管理服务,覆盖 Serverless、边缘计算、分布式云等多种业务部署场景,业内首创单个集群兼容多种计算节点的容器资源管理模式。同时产品作为云原生 Finops 领先布道者,主导开源项目Crane,全面助力客户实现资源优化、成本控制。
    领券
    问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档