软件分层的思考

750 阅读5分钟

软件分层的思考

1.传统分层

传统分层中,上层依赖下层。每层定义了接口和实现,上层的实现依赖下层提供的接口。

背后的寓意:服务的提供方(下)掌握了接口定义的话语权,调用方(上)根据自己需要调用服务方提供接口,上层需要把参数转换为下层要求的类型。

比如:DAO定义了持久化到数据库的标准,Service层按照DAO层定义的接口进行调用。

image-20220707155621671.png

2. 依赖倒置分层

通过依赖倒置,上层依赖与下层的接口,而不是实现;这样说并不准确,严格说来是下层实现了的上层定义的接口。

背后的隐喻:上层掌握了标准的话语权,上层根据自己的需要定义服务标准,可外包不同实现方实现,实现方只要按标准完成就可以;实际依赖关系已经发生了反转。

比如:领域服务Service层来定义数据持久化标准repository,repository的接口定义不再属于DAO层,而是属于领域服务层。Repotitory-DB-impl是一个外包实现,用数据库层实现此标准。

image-20220707155659447.png

3.DDD分层

在DDD分层是依赖倒置的一个使用场景,领域服务占据程序的核心设计,承担了大脑的功能。大脑只要思考发出命令就可以,具体的执行由不同的执行器官来做就好;命令的格式由领域层这个大脑来规定。上图2其实就是领域驱动设计的分层的,实际使用可以不用分的那么精细,根据需要可以有一些变体,核心思想对就可以,比如下图:repository-interface(持久化接口)不用单独一个层,直接放入了Domian(领域服务层)中,repository-db(持久化的DB实现)直接依赖整个domain也是可以的。

image-20220707155731382.png

4.六边形架构

六边形架构其实就是把依赖反转中领域逻辑占核心的思想进一个彻底,在架构场景中,领域逻辑是老大,制定了各种标准,其他层只要实现这些标准,辅助实现领域逻辑的战略目标。比如我们的程序逻辑中,保存数据到数据库,发送邮件这些基础服务并不是我们程序的核心,程序核心只要定义好接口,具体的实现委托出去就好;程序核心关注与核心逻辑和定义标准就可以,不用和具体的实现打交道。(可以类比大脑和身体器官)

image-20220707155758341.png

大脑的六边形设计:

人的大脑是一个典型的六边形架构,大脑虽然清大,但大脑自己做很多具体的事都不会做,看东西?走路?都不会,它躲在脑袋内部,通过委托出去的各种外设和外界打交道(眼睛,胳膊,腿等器官)。

比如大脑需要决策当前的道路是否可以继续前进:
1. 它不会自己去看,大脑会定义个外界视频描述接口;
2. 眼睛实现了大脑需要视频信号的接口,大脑得到眼睛的输入视频,通过图像识别和经验判断,决策道路通畅可以继续前进;
3. 大脑再对行动器官发出移动指令继续前进(如果是人行动器官就是腿,如果是鸟类那就是翅膀,对应的器官实现了移动这个接口)。

5. 分层的好处与树

分层与树: 上文我们讨论的是上下分层,更通用的分层是树形,当树只有一个枝干就会退化为上下分层。

分层在大自然的中处处可见,或者说是造物者的常用设计。下图是秋天的落叶,树叶脱离枝干,散落地上,很凌乱。

落叶.jpeg

再回到夏天,树叶有序的长在树上。树是一个整体,由树干,树枝,树叶组成(树干是第一层,大的树枝是第二层。。。,树叶是末层)。我们可以很清晰观察树枝或树梢的绿叶,甚至可以方便的去寻找嫩叶或枯叶,成千上万的树叶通过树形结构的管理,变的整体有序。 树干,树枝,树叶结构

通过上面两个数和落叶的对比图,证明了树形结构可以非常好的管理了复杂性 ,树形结构是大自然创造使用非常普遍的设计,你基本上可以在很多植物,动物以及万物上发现树形的设计。

软件: 软件最大的挑战就是处理复杂性,既然树可以处理复杂性,那么自然软件也可以采用这个思想;比如我们常用的文件夹也是树形结构,上面我们讨论的软件分层也是树形的一种。

6. 软件的执行代码与树

1-4部分讨论的软件主体结构使用的分层,如果喜欢到代码级别呢?我们都知道,程序就是一行行可以执行的二进制指令,就是平铺一行行代码,不抽取任何类和方法,计算机执行是没有任何问题的。有问题的是人,我们人没有办法读懂和维护。

所以我们借鉴了树的设计,计算机的软件中的每行代码执行逻辑就像是树叶,代码平铺就好像散落一地的树叶,但我们很难看懂或维护。通过树形整理之后,代码分成了模块(树干),类(大枝干),方法(下枝干),代码行(树叶),形成整体上一个非常有序的树,代码就非常方便进行管理和维护了。