Day927.如何进行组件化分析和设计? -系统重构实战

如何进行组件化分析和设计?

Hi,我是阿昌,今天学习记录的是关于如何进行组件化分析和设计?的内容。


一、Sharing 1.0:案例诊断

对 Sharing 做个案例诊断。

1、代码结构

Sharing 1.0 采用的是单体的架构,所有的的代码都在一个模块中,主要包含了账户、文件和消息 3 个模块。

  • 账户模块主要管理用户个人信息、登录及登出;

  • 文件模块主要负责用户上传文件及浏览文件;

  • 消息模块主要负责用户共享文件给所有用户。

另外,Sharing 代码的组织方式是按技术维度来划分,并不是以业务维度进行划分,这是单体架构常见的代码组织方式。

Sharing 主要的包结构和功能梳理了一张表。

Day927.如何进行组件化分析和设计? -系统重构实战_第1张图片

按技术维度组织代码最大的问题就是:如果缺少架构约束,容易导致代码随意依赖,耦合度高。

所以。建议是代码的组织方式最好以业务维度来组织,这样代码可以更加内聚,架构依赖的检查规则也更容易编写

例如业务模块之间的横向依赖,消息主页面依赖了文件模块及账户模块的代码,像后面图里展示的这样。

再比如一些基础的组件直接依赖业务模块的代码。

Day927.如何进行组件化分析和设计? -系统重构实战_第2张图片

总的来说,Sharing 目前的代码结构主要是以技术维度来组织代码,但由于缺少架构约束,内部的代码耦合度高。


2、工程管理

Sharing 目前采用的是单个 Git 仓管理的方式,但由于前面的业务划分不清晰,导致很多时候多个开发修改到同一处代码,这样在代码提交时非常容易产生冲突。

另外,团队也没有统一的分支策略,通常有多个并行的开发分支和线上分支需要维护。

可以结合下图理解。

Day927.如何进行组件化分析和设计? -系统重构实战_第3张图片

可以看出,团队缺少统一的分支模型,开发人员随意拉取分支,各个特性的代码不能及时同步,没有一个分支拥有代码的全集。

随着时间的推移,分支上的代码差异越来越大,大家也不敢随意合并分支代码,只能通过 cherry pick的方式来同步一小部分代码。


另外,很多线上问题也经常是由于那部分代码没有同步导致的。在这么无序的分支模型下,来看看团队是怎么来管理制品的生成。

团队使用了 Jenkins 搭建了一个简单的流水线,主要是为了方便测试人员触发打包进行手工验证。


同样画了一张图帮你理解。

Day927.如何进行组件化分析和设计? -系统重构实战_第4张图片

从图看出,测试人员在测试时会通过 Jenkins 平台手动选择需要打包的分支,然后点击进行构建,构建完成后下载安装包到本地安装。

从作用上来看,流水线变成了一个“打包平台”,仅服务于测试人员,对开发人员无感。

针对 Sharing 项目的这种情况,怎么改进呢?

  • 建议在架构上,通过组件化让各个模块的代码边界更加清晰,减少代码的随意依赖。同时,这也能让各个组件的职责更加单一、明确,便于代码扩展。

  • 工程上,我们可以结合组件化架构搭建分层、分级的流水线,增加门禁守护以及版本自动化构建,统一规范,减少人工参与版本的发布。


看看这张项目诊断表:

Day927.如何进行组件化分析和设计? -系统重构实战_第5张图片


二、Sharing 2.0:改进设计

对 Sharing 的优化主要分为两个部分:架构和工程实践。

组件化架构的设计有两个重要的核心工作:

  • 第一个是划分组件
  • 第二个是把这些组件组织成一个系统。

1、组件划分

在维基百科中提到,基于组件的开发(Component-Based Development,简称 CBD)是针对系统的广泛功能,进行关注点分离的软件工程方式。

此方式是以复用为基础的作法,定义、实现许多松耦合的独立组件(Component),再将组件组合成系统。这其中有几个关键词已经说明了组件化的好处,包括关注点分离、松耦合和复用。

做组件化设计时一定会遇到一个问题,就是如何划分组件?

先来看看在移动应用中有哪些常见的组件,基于之前的经验,将组件划分为 3 种类型,可以参考梳理的表格。
Day927.如何进行组件化分析和设计? -系统重构实战_第6张图片

通常来说,在项目代码中,技术组件和功能组件比较好识别,因为它们有一个共同的特点:被多个业务使用,组件之间的边界彼此也相对清晰。所以,业务组件的划分可以参考 UI 设计。

一般情况下,产品在设计时都会将相对内聚的功能组织在一个页面上,便于用户使用。这点也是移动应用在组件划分上相较于后端微服务划分的一个优势。


下面按照业务、功能和技术这 3 种组件类型,对 Sharing 项目进行一次组件的全景梳理。

先来划分业务组件。根据页面的设计,产品划分了三个功能模块,分别为消息、文件和账户。

由此,可以划分出三大业务组件:消息组件、文件组件和账户组件,然后将相关联的包或类归属到对应的组件下。

注意,在梳理哪些类属于这个组件时,建议根据用户的使用路径,从一开始的操作入口的页面类开始,这样最简单。

然后接着查看一下这个类的依赖和引用情况,如果该类频繁与某个业务组件内的类有交互,那么这个类大概率也要划分在对应的组件内。

在实际项目中,一个组件内的类可能成百上千,这个时候我们可以先从包的维度来分析。

根据前面的分析,Sharing 的三大业务组件最后划分如下:

Day927.如何进行组件化分析和设计? -系统重构实战_第7张图片

接着,来梳理功能组件。在梳理功能组件时,同样建议先查看被前面业务组件多次引用的类,如果一个类被多个业务组件所引用,那么大概率这个类要被划分到功能组件的范围。

比如 Sharing 中的文件上传下载功能,这个功能会同时被消息和文件模块使用,对此,可以考虑将其作为独立的功能组件。

Day927.如何进行组件化分析和设计? -系统重构实战_第8张图片


最后,来梳理一下技术组件,依旧通过查看引用的方式来判断。

功能组件和技术组件经常被混淆,其实区分技术组件与功能组件的依据是:

技术组件能放在任何一个应用里都能使用,与具体的业务不产生关系,而功能组件不一定都行。

Day927.如何进行组件化分析和设计? -系统重构实战_第9张图片


三、组件组合

划分好组件以后,就可以进行架构设计了。

架构的设计重点就是将这些组件组合成系统,明确这些组件之间的依赖关系和约束条件。

组件组合的关键是管理好组件之间的依赖,从依赖方向上来看,这三类组件的依赖关系应该是:业务组件 -> 功能组件 -> 技术组件

根据这个依赖方向,再抽象一个分层的概念,将各类组件划分到不同的分层中,这样边界职责就更加清晰了。


基于这个分析,重新设计 Sharing 2.0 的组件化架构。

Day927.如何进行组件化分析和设计? -系统重构实战_第10张图片

Shariing 2.0 新的架构设计主要包含三个横向的分层,依次对应着三类组件。

  • 第一层是业务层,主要承载的是各类独立演进的组件。
  • 第二层是框架层,主要承载的是各类复用的功能组件。
  • 第三层是基础组件层,主要承载的是各类公用的技术组件。

特别需要注意的是,在架构设计中有一个基座的功能组件,该组件主要作为各个业务组件的底座,能灵活插拔各个业务组件。


根据新的分层架构设计,Sharing 2.0 架构有两个重要的约束原则:

  • 纵向规则:上层组件可以依赖下层组件,下层组件不能反向依赖上层的组件。
  • 横向规则:业务组件之间不能有直接的依赖,功能及技术组件之间尽量减少依赖。

四、总结

遗留系统常见的代码组织方式是按技术维度来组织,如果缺少规范和架构约束,非常容易出现代码随意依赖、耦合度高的问题。

所以,应尽可能以业务的维度来组织代码,这样更易于维护。而遗留系统在工程上的问题往往也是缺少规范和过程约束,更容易加剧代码的腐化。针对 Sharing 1.0 的架构问题,进行了组件划分和架构设计。


将组件划分为业务组件、功能组件和技术组件:

  • 业务组件主要是承载业务,可复用性低;
  • 功能组件通常是业务组件的一部分,被各个业务组件复用;
  • 技术组件主要是支撑业务的开发,与业务不关联,能在多个应用之间进行复用。

结合组件的划分,设计了新的三层架构来组织这三类组件,分别是业务层、框架层和基础组件层。而这种架构思想就是:业务独立演进,公共能力复用。


你可能感兴趣的:(业务设计,重构,架构,框架设计,组件,组件化)