【架构艺术】代码架构治理之四层境界

2024-06-02 15:52

本文主要是介绍【架构艺术】代码架构治理之四层境界,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

最近逐渐开始写一些简单且稍微务虚的文章。原因有挺多,其一是,自己的工作内容和企业的内部情况绑定的更加深入了,许多信息如果要在互联网上分享,需要考虑在很多地方做加工;其二是,过分拘泥于非常深度的技术挖掘,可能只能涉及到一些特定的领域,不利于技术博客的持续运营,并且从读者的视角,形式简单但内容富有思考的干货,才是真正有价值的产出。

因此,今天这篇文章,就从笔者自己的角度,谈一下代码架构治理的四层境界,把读者自己最深层的思考内容给解剖出来。希望这篇文章能够帮助到一些在代码架构治理工作方面,感受到痛点的同行们,让大家可以通过文章提到的一些思维工具,去解决实际工作中代码架构治理方面的问题。

这四层境界分别是:

  1. 套设计模式
  2. 自上而下需求拆解
  3. 自底向上模块抽象
  4. 网状概念聚类分层

第一层境界是套设计模式。犹记得刚开始接触代码工程架构的时候,我们都被灌输了很多设计模式相关的概念,小到工厂、责任链,大到DDD、BDD。这些看起来很高大上的名字,它们的实质是什么?是工具,是最为基础的代码架构思维工具。一个工具要有用武之地,必然有其背后合适的业务场景。理论上来讲,大多数的代码架构问题,通过套设计模式,遵循基本的重构原则,都是可以解决的。

设计模式不能解决的问题是什么呢?答案是:未知的领域。通俗地理解,设计模式就是前人已有的经验,在某类业务或者技术场景之下,沉淀出来的一套代码范式。但面对未知的领域,以前的设计模式是否可以起作用,哪些设计模式最为适合,都不是能够直接无脑确定的。未知的领域背后,本质上是未知的概念联系,如果直接套用某类设计模式,那么将来如果引入新的需求场景,既往的设计模式不适用,就会出现重构成本。

现今有很多技术同行的简历或者PPT上,都可能写通过DDD、BDD的思想,解决了某类技术问题。从笔者的角度认为,不同领域的概念模型其实是五花八门的,如果真的某类场景用了经典方法解决,要么是这类场景已经被研究透了,架构层面缺乏创新潜质,要么是自身实力不足,对技术缺乏独立思考,没有能力去灵活调配代码的架构,只能通过既有的思维去生搬硬套。如果有意识在简历或PPT重突出这类信息,这样的人才,假使面对未知的业务或技术领域,一定很难有能力去cover住代码架构。套设计模式的是一类人,如今,套GPT的也是这一类人。

第二层境界是自上而下需求拆解。需求拆解可以解决未知领域代码建模的问题,弥补纯设计模式的不足。做代码架构,本身即是对某类业务或技术场景的建模,当我们需要解决某些具体的问题时,一个最简便的办法是对需求本身做拆解,比如用金字塔模型,把大的问题划分为小的问题,然后分而治之。这样的一个好处是,我们很容易去构建出模块化、低耦合的代码架构模型,因为每一个需求的子问题都可以用单独的一套代码去解决。并且,在协同开发场景下,还能够保证各司其职,互不干扰,形成一套很完善的开发体系。

自上而下需求拆解,解决不了的问题是什么?答案是:认知的一致性。在先前的一篇文章里,通过一个自动化框架的例子就说明了这个道理,需求拆解是自上而下的,但技术实现是自底向上的。为什么要自底向上,其本质诉求就是在工程初始化环节,把最基础的认知概念给统一抽象起来,认知的一致性越多,代码需要受迫维护的内容就会越少。如果在工程代码开发方面,无脑通过需求拆解的方式构建不同的模块,那么必然会出现很多具备重复意义的代码。久而久之,就会形成技术债。

因此,要解决这个问题,我们需要踏入第三层境界,自底向上模块抽象。当需求自上而下拆解完成后,还有一个重要步骤是,把最底层需求涉及的共性概念给抽象出来,构建成一套公用基架。这套基架不仅是提升了代码的易维护性,而且更重要的,是决定了这个领域的基本概念认知。以游戏开发为例子,一个客户端研发团队,除了业务Gameplay研发的成员之外,一定还有部分成员会专攻游戏引擎的研发,去做好整块客户端代码的基架。有了这个基架,就不容易出现你实现一套,我实现一套的问题,从而让整个工程架构的底层逻辑都通顺起来。

对于一些小的研发团队,或者是个人开发者,在工程代码的呈现方面,很容易出现踏入第二层境界,但无法踏入第三层境界的情况,导致工程能力不能长久迭代。解决这个问题的方法就是,下手慢一拍。如果是在时间紧张的情况下,需要注意在写完demo期代码之后,顺便构思好代码重构的路径,留有后手。做出10分,交付7分,这样就能够保证工作产出的弹性。

当然,自底向上模块抽象,也有解决不了的问题,那就是概念分层。如果一味陷入共性抽象,一味通过【加一层】的方法解决技术问题,就容易出现层次冗余,难以重构的情况。一套抽象下来,看起来代码可读性不错,但整个工程的内在结构太复杂,就会导致可读性不高。虽然每块代码的责任是分明了,但不同模块之间的关系很不清晰。A调了B,B调了C,C又调了A,从而导致代码之间出现循环依赖的风险。然后,哪天项目需要升级了,要么就是弄个V2,要么还往原来的层次上加,这样就会降低整个项目的可迁移可复用能力。

要解决这个问题,我们就需要踏入第四层境界,网状概念聚类分层。我们需要了解一个本质是,不论是那种业务或技术领域,底层概念之间的关系,都是网状结构的。通过纯代码的方式,不可能模拟网状结构的概念,但是我们可以通过聚类分层的方式,把一些同质的概念放到相同的层次,并且同时保证层次的数量尽量少,从而在尽可能简明工程架构的同时,达到需求预期的效果。

那么,如何去把聚类分层这个事情给做好呢?一个重要的关键点就是,根据不同的视角,来划分不同的层次。举个例子,一个后端服务,从服务框架的视角,可以分出来handler/service/dal/util几个层次;从业务视角,可以在service内部,分出来app/core/3rd等几个层次(当然,微服务的话,可以把3rd提到外面,app跟core都不要)。基本上一个后端项目,代码最多3~4层就可以解决问题,如果还存在需要加一层的情况,就从更高的服务架构维度去解决,而不是再拘泥于已有的代码项目。

分清每块代码的责任很重要,但如何构建每块代码的层次梯度也很重要。解决了低耦合问题,也要解决高内聚问题,这样才能让整个代码的架构变得游刃有余。

这篇关于【架构艺术】代码架构治理之四层境界的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/1024412

相关文章

Java集合之Iterator迭代器实现代码解析

《Java集合之Iterator迭代器实现代码解析》迭代器Iterator是Java集合框架中的一个核心接口,位于java.util包下,它定义了一种标准的元素访问机制,为各种集合类型提供了一种统一的... 目录一、什么是Iterator二、Iterator的核心方法三、基本使用示例四、Iterator的工

Java 线程池+分布式实现代码

《Java线程池+分布式实现代码》在Java开发中,池通过预先创建并管理一定数量的资源,避免频繁创建和销毁资源带来的性能开销,从而提高系统效率,:本文主要介绍Java线程池+分布式实现代码,需要... 目录1. 线程池1.1 自定义线程池实现1.1.1 线程池核心1.1.2 代码示例1.2 总结流程2. J

Spring Boot分层架构详解之从Controller到Service再到Mapper的完整流程(用户管理系统为例)

《SpringBoot分层架构详解之从Controller到Service再到Mapper的完整流程(用户管理系统为例)》本文将以一个实际案例(用户管理系统)为例,详细解析SpringBoot中Co... 目录引言:为什么学习Spring Boot分层架构?第一部分:Spring Boot的整体架构1.1

JS纯前端实现浏览器语音播报、朗读功能的完整代码

《JS纯前端实现浏览器语音播报、朗读功能的完整代码》在现代互联网的发展中,语音技术正逐渐成为改变用户体验的重要一环,下面:本文主要介绍JS纯前端实现浏览器语音播报、朗读功能的相关资料,文中通过代码... 目录一、朗读单条文本:① 语音自选参数,按钮控制语音:② 效果图:二、朗读多条文本:① 语音有默认值:②

Vue实现路由守卫的示例代码

《Vue实现路由守卫的示例代码》Vue路由守卫是控制页面导航的钩子函数,主要用于鉴权、数据预加载等场景,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着... 目录一、概念二、类型三、实战一、概念路由守卫(Navigation Guards)本质上就是 在路

uni-app小程序项目中实现前端图片压缩实现方式(附详细代码)

《uni-app小程序项目中实现前端图片压缩实现方式(附详细代码)》在uni-app开发中,文件上传和图片处理是很常见的需求,但也经常会遇到各种问题,下面:本文主要介绍uni-app小程序项目中实... 目录方式一:使用<canvas>实现图片压缩(推荐,兼容性好)示例代码(小程序平台):方式二:使用uni

JAVA实现Token自动续期机制的示例代码

《JAVA实现Token自动续期机制的示例代码》本文主要介绍了JAVA实现Token自动续期机制的示例代码,通过动态调整会话生命周期平衡安全性与用户体验,解决固定有效期Token带来的风险与不便,感兴... 目录1. 固定有效期Token的内在局限性2. 自动续期机制:兼顾安全与体验的解决方案3. 总结PS

C#中通过Response.Headers设置自定义参数的代码示例

《C#中通过Response.Headers设置自定义参数的代码示例》:本文主要介绍C#中通过Response.Headers设置自定义响应头的方法,涵盖基础添加、安全校验、生产实践及调试技巧,强... 目录一、基础设置方法1. 直接添加自定义头2. 批量设置模式二、高级配置技巧1. 安全校验机制2. 类型

Python屏幕抓取和录制的详细代码示例

《Python屏幕抓取和录制的详细代码示例》随着现代计算机性能的提高和网络速度的加快,越来越多的用户需要对他们的屏幕进行录制,:本文主要介绍Python屏幕抓取和录制的相关资料,需要的朋友可以参考... 目录一、常用 python 屏幕抓取库二、pyautogui 截屏示例三、mss 高性能截图四、Pill

使用MapStruct实现Java对象映射的示例代码

《使用MapStruct实现Java对象映射的示例代码》本文主要介绍了使用MapStruct实现Java对象映射的示例代码,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,... 目录一、什么是 MapStruct?二、实战演练:三步集成 MapStruct第一步:添加 Mave