最少改动 x 最大收益
有一个任务,要调整介面上的表格数据:
你发现有太多的其他功能,都要使用到这个数据。
这里一改动,就代表了全部都要一起改。
两者建立了依赖关系,这种行为在软件中也会称为:
「耦合」
高内聚 低耦合
要怎麽达成 ?
耦合性三大原则
可以先帮你实现低耦合的目标。
「软件」是一种很神奇的东西,看似很自由,可以随意添加新的功能。
自由的空间,反而会越来越少 (越来越难改动)
看似多了限制,却反而能使得,未来的扩展空间 大大的增加。
「违反直觉」延伸阅读 :
整洁的软件设计与架构篇
除了「物件导向的五大设计原则」以外,还有「元件的内聚性原则」与「元件的耦合性原则」。
实际上的顺序,应该是要:
内聚性先,而耦合性後
因为我个人认为「耦合性」的概念,比较好懂; 原则的部分,也相对容易,应用於开发上。
这次,会先说明耦合性的部分
下一篇章,会接着继续说明内聚性的部分
在元件的依赖关系图中不允许出现环
朝着稳定方向进行依赖
元件的抽象程度应该与元件的稳定程度一致
Acyclic Dependencies Principle
在元件的依赖关系图中不允许出现环
从字面上来理解,就是元件在需要其他的元件工作时,之间构成的依赖关系,不可以是环状循环。
因为依赖於其他元件,目的是为了
「减轻工作量」
别的元件有做过的事情,就不要重新再做一次。
如果元件的依赖会互相参照,代表 :
就好像构成了 一个短路循环 ,直到系统**「过载」**
从「减轻工作量」这个角度来看,「循环依赖」更像是一个工作制造机
可以源源不绝的,让你有做不完的工作。(不会失业 XD)
Stable Dependencies Principle
朝着稳定方向进行依赖
延续无环依赖原则的思路,除了依赖不能造成循环,依赖还是最好有个方向。
这个方向的路标,就是「稳定度」
也是以「工作量」的多寡来决定
元件被很多的功能依赖,但本身没有去依赖任何东西
改了它,就代表了巨大的「工作量」
所以这个元件是「稳定」的
如果这个元件,没有功能依赖它,但它依赖了很多外部的元件
修改它的「工作量」非常的低
所以这个元件是「不稳定」的
藉由依赖的关系数量,这里就会有一个的公式,可以计算元件的稳定度
理想的状况,就是由不稳定的元件,朝向稳定的元件,建立依赖关系
Stable Abstractions Principle
元件的抽象程度 应该与元件的稳定程度一致
也就是越重要的元件,应该越只表达纯粹的「概念」
稳定的核心元件,虽然稳定,但失去弹性不能扩增,并不是软件设计想要看到的情况。
以餐厅来说,厨师就是稳定的核心元件
由厨师本身会煮什麽菜,来决定餐厅会有什麽样的菜单
对於,有点规模的餐听,这并不是一个好的情况
这边的原则,就是将表达**「概念」的「菜单」**,当成是最稳定的核心元件
如此,就不会受到限制。各个连锁店的厨师,也能根据菜单的菜谱,快速增加新的菜色。
依据耦合性的原则,领域驱动设计的概念,补充实作部份的三个细节:
通常就是系统的核心,所以 Domain 的 Service 通常会宣告成 Interface 的介面
名称结尾为 Service
然後,在同目录的 impl/ 资料夹,创建新的类别实作(implements) 该 Service 的介面
名称结尾为 ServiceImpl
这里是借鉴了 「SAP 稳定抽象原则」,越稳定的元件应该越抽象。
负责的是流程作业,相比於 Domain 层变动性是比较大的,虽然说同样有 Service 的类别,但不再创建 Interface 的介面
结尾的名称命名 使用 AppService
这里是借鉴了 「SDP 稳定依赖原则」,把容易变动的东西,变得更加容易改动。
提供所有的技术支援,从 DDD 的架构分层可以很明显地看到,它是个自上而下的依赖关系
但对於与 Domain 层的关系,我认为不应该被领域层的元件所依赖
DAO , Data Access Object
领域层(Domain Layer)的服务(Service) ,不应该直接 调用 DAO 来完成资料保存的任务
而是应该提升一个层级,交由应用层(Application) 来执行这项任务
避免资料库的变动会影响到领域层(Domain Layer)的功能
util 工具,通常会是各种第三方的框架,封装而来
如果,第三方的框架:
有重大的 bug
有更好的框架可以更换
调整 util 元件,就会影响到 领域层(Domain Layer) 的功能
这种情况...
不如就由领域层(Domain Layer) 提供 :
然後由,基础设施层来实作功能。
不管最後是使用什麽样的技术实作,只要能够通过,领域层的单元测试,就可以确保系统的正确性。
这部分,可能一时之间无法转换过来,不过这里要表达的就是:
Domain 层 是稳定的核心元件,不应该去依赖其他层级的元件。
依据上述耦合性的三大原则,有没有发现一件事情:
**「稳定」与「不稳定」**并不是一个「好」与「坏」的关系
而是这个「稳定度」与元件的「特性」是否是相符合。
最容易变动的「使用者介面层」、「应用层」,就是放在上两层,向下依赖
不敢说是最好的「设计」,但我知道 :
建立关系
不应该是那麽的随心所欲
朝着正确的方向不断精进,也许哪一天也可以触碰到传说中:
「最少改动,最大收益」
软件开发的天堂之境
只有资深工程师才有资格跟工程师说:「应该很简单」
-- Gamma Ray Studio
本节是以 Golang 上游 8854368cb076ea9a2b71c8b3c8f675a8e1...
这次练习的题目是做出商城中产生订单的功能 功能主要需求:产生订单 (目前一笔订单只能买一个品项)、库...
从 WFH 的 三个半月多 ( 2021- 05, 06, 07, 08) 再回到 办公室 &am...
上次学习了基本的阵列语法 这次要来练习简单的阵列使用 都是基本的宣告以及画面显示 主要是练习一维阵列...
全文同步於个人 Docusaurus Blog Foreword 过往前後端沟通,需要仰赖 cli...