在现代应用程序开发中,信息流(Feed)是许多平台核心功能的一部分。信息流往往会聚合大量的数据,构建这样一个信息流列表是一个复杂的任务。需要从多个微服务和数据库中获取大量数据,包括用户、频道、标签、等级、用户状态和互动等,并进行过滤、转换和计算,最终拼装成目标数据结构。在这个过程中,性能和代码设计的合理性尤为重要。

难题:一个超过1000行的长函数
在互联网服务端代码中,分层架构是一种常见的业务逻辑组织方式。我们通常根据实体,将每一层分为以实体名称命名的文件和无状态对象,每个对象包含数据获取、业务逻辑处理和数据库读写的方法。
通常情况下,大多数方法都是内聚的,只与单个实体相关,代码行数较少。但类似于微服务中的聚合根,无论数据结构如何设计组织,服务端接口最终需要根据产品和业务的需求,在前后端的交界处,为了满足UI展示的需求,将数据聚合起来。无论架构层面如何治理和拆分,为满足业务需求,接口层必然需要将数据按照使用需求进行组合。
信息流产品层面正是这样的场景。信息流列表中会聚合各种不同类型的信息和广告,以及信息作者的状态、互动数据和统计信息。为了满足这些需求,需要从各种数据源或服务中获取数据,并根据不同领域逻辑进行转换和组合,最终拼装成目标数据结构。在考虑性能的情况下,这些拼装数据的函数往往变得非常庞大。
在我参与的一个项目中,就遇到过一个信息流列表对象拼装函数。由于处理复杂数据,该函数长度超过1000行,甚至接近2000行,维护起来非常痛苦。
抽象和组合:拆分复杂函数
大多数小型业务探索驱动的项目,由于开发时间短、变化快,往往不会在代码设计上花费太多时间。开发人员也不愿意在调用业务逻辑函数时进行复杂的组装,因此很容易出现Service中包含一个长函数,并通过包的公开方法直接访问的情况。
为了降低代码复杂度并解耦核心逻辑和具体实现,在重构复杂长函数的过程中,我采用了以下方法,使代码能够适应微服务架构。无论外部数据获取代码如何变化,核心的信息流拼装逻辑都不会受到影响。具体方法非常类似六边形架构的思想。
代码重构的核心思想可以总结为:采用六边形架构,将核心业务逻辑与数据获取和转换方法分离,通过工厂模式和依赖倒置实现灵活的架构设计。
具体实现思路
我把这种模式称之为组装工厂,像流水线一样,初始化一个空对象,然后逐步把各种字段拼到对应位置,最后交付一个完整的对象。

最低0.47元/天 解锁文章
913

被折叠的 条评论
为什么被折叠?



