适当时机 x 适当分类
全新的专案,从无到有的开发
打算把很多重复的功能,都聚集成 一个独立的元件
要将哪个类别归类到哪个元件,是个重大的决定!
但大部分的时候,却都是凭感觉分类。
就是在告诉你 :
分类时,可以依据类别的什麽特性,来归类成同一个元件。
除此之外 :
它甚至告诉你,现在就将类别,抽成共用元件,并不是恰当的「时机点」。
延续元件耦合性的部分
在上一篇章中,已经知道:
元件之间建立关系,不应该是那麽的「随心所欲」
高内聚在前,除了类别要先内聚成大颗粒的元件,才能互相依赖以外。从元件内部来看,如果都是相似且恰当的类别,那麽元件在要使用特定功能时,要依赖的元件,就不会是分布於程序各处,而会相对集中。
元件只会依赖必要的元件,整体系统的参照数量,就会降低。
同时也达成「低耦合」的目标
再使用性的细致度就是发布的细致度
将那些会因着相同理由、再相同时间发生变化的类别,收集到相同的元件之中。
将那些在不同时间、因着不同理由发生变化的类别,分割到不同的元件之中。
不要强迫元件的使用者依赖他们不需要使用的东西
The Reuse/Release Equivalence Principle
再使用性的细致度就是发布的细致度
这个原则是再说明,真正可以「再使用」的「元件」,必须是像发布应用程序一样;
拥有独立的版本号与说明文件能够「追踪」与「纪录」每一个时期,程序的变化,才是符合「再使用」的元件特性。
也就是
再使用的「元件」,必须是已经「发布」过的元件
这麽做的目的,是不希望当要使用现成的程序功能时,只是纯粹的程序码「复制」、「贴上」
後续如果那段程序被更动了,追踪与管理都会是一个大问题。
更严谨的做法,就是将要「重用」的程序,独立成一个可以任意部属的元件。
在其他应用程序中,只需要知道外部的接口,而不需要知道原始的程序码。
能够方便的使用,也是「再使用性」的特徵
The Common Closure Principle
将那些会因着相同理由、再相同时间发生变化的类别,收集到相同的元件之中。
将那些在不同时间、因着不同理由发生变化的类别,分割到不同的元件之中。
上一个 REP 原则,说明 要「再使用」的元件,必须要像应用程序一样发布
因此,元件内部的类别组成,就必须要能够实际的解决:
特定的主题
特殊的目的
也就是「内聚性」必须要强
但该原则并没有具体的说明,怎样才算是「内聚性」强
「CCP 共同封闭原则」与 「CRP 共同重复使用原则」就是用来补充 REP 原则,未具体说明的部分。
从描述上来看,可以很明显地知道。分类的依据就是根据「变化」的可能性进行分类
因为软件虽然是可变的,但还是希望「最少改动,最大收益」。
如果程序需要被更改,那麽当然希望更改的地方,都集中在同一个元件,而不是分散开来,到处都是。
The Common Reuse Principle
不要强迫元件的使用者依赖他们不需要使用的东西
使用「变化」的可能性,进行分类後。
这个原则,则是要将分类好的元件内部,在做一个更细致的分类。
因为一个元件中,使用者有可能只用了这个元件的很小一部分,其他的部分并不是使用者所需要的。
但依赖的关系仍然是建立,这个元件其他部分更动了,还是必须要重新编译、验证、布署。
如果有更精简的元件可以使用,就没有理由非得要选择你的元件
所以,为了更强的内聚性,就是以使用者的角度,将元件进行分割
元件内的类别,都是使用者刚好要使用到的部分 (元件不要依赖不需要的东西)
依据上述的三个原则,可以发现每个原则,所关注的重点都不太一样 :
目标: 让元件更好的被使用
关注的是「重用性」
目标: 让元件更好的被维护
关注的是「发展性」
目标: 让元件更精准的定位
关注的是「精确性」
这三个原则,彼此之间会互相拉扯,太多的关注某些原则,就会导致另外一个原则无法被确切的符合。
这种情况,可以描述成一个张力图:
当开发者只关注其中的两个顶点,而放弃另外一个顶点的原则时,程序必须要付出的代价。
元件就会很难被重用
修改时就会有太多的元件要被更动
造成太多不必要的版本发布
因此在软件设计中,还有一个必须要考虑的因素:
时间维度
对於大多数的应用程序,由於想要 :
「可发展性」的重要程度通常会大於「可重用性」
也就是说,在专案开发初期:
CCP 原则的重要性会大於 REP原则(可发展比重复使用更重要)
所以这时,第一个应该要思考的是
如何恰当的「分类」,而不是思考未来该如何「重用」。
重用的部分,必须加入了 CRP 原则,更精简後,依循 REP 原则正式发布:
此时,你的元件才会真正意义上的,具有「高内聚」的特性。
回头来看 DDD 领域驱动设计
四个分层,其实就是 CCP 原则的概略呈现。
而在每一层中,我通常的做法,都会在更细致的依据业务情境,进行分类:
每个业务情境都会有各自的 Service Entity 与 vo
每个业务流程也都会有各自的 Service 与 DTO
这种细致化的方式,也是 CCP 原则 与 CRP 原则的综合应用。
就像是我的 :
JavaProjUtil
iOSProjUtil
各种 Util 结尾的专案,可以独立的发布版本与提供说明文件。
软件是一个动态的东西,设计软件元件内部的内聚性原则也是动态的。
身为优秀的软件工程师,可能就会意识到,这个就是:
「软件的本质」 与 「软件的特性」
掌握了这些原则,你就能:
在适当的时机点,出现适当的东西。
软件的天堂之境:「最少改动,最大收益」,已经出现在不远处。
有想法的人很多,有作法的人很少
-- 我以前的组长
<<: Day 26 - 当AI有了常识之後, 超越人类? -GAN(2)
Elastic Load Balancing 可在多个目标 (例如 Amazon EC2 执行个体、...
在 E2E 测试撰写时,前端可以利用 aria-label 或客制化的 testing tag 来方...
今天要来进入到生命周期的第二个环节: Updating 更新,继上篇的 Mounting 元件挂载...
目前近几年的不管是唱片 演唱会 线上设计风格开始走向几何风格形象 金曲30很美的背景设计 gerne...
JavaScript (简称JS)是一种物件导向的程序语言 "object orient ...