架构设计中的正交原则

发布时间 2023-07-26 11:16:03作者: 邴越

正交设计,是普遍的设计原则,与粒度无关,与编程范式无关,更与具体的实现语言无关。

一、正交设计原则
“正交性”是几何学中的术语,互为直角的直角坐标系就具有正交性;在计算技术中表示不依赖性或解耦性。

一种相互正交的模块化思想,模块内有更高的内聚,与模块外有更低的耦合,只有一个不变的交叉点,这个交叉点就是我们所说的接口。而我们所说的正交设计原则,就是要保持模块内高内聚、模块外低耦合的正交性稳定不变。

非正交的系统意味着系统中各组件互相高度依赖,这类系统中是不再有局部修正的情况了。

二、正交的好处
1、提高生产率
改动得以局部化,所以开发时间和测试时间得以降低。
正交还能促进复用。
基于正交的组件进行组合,生产率会有相当微妙的提高。(例:windows的GUI,和Unix的各个小命令)
2、降低风险
能降低开发中固有的风险。
有问题的代码区域被隔离。
所得系统更健壮。
正交系统能得到更好的测试。
不会与特定的供应商、产品、或是平台捆绑在一起。
三、如何实现正交设计原则
那么如何保持这个正交原则呢,最终目的就是为了高内聚和低耦合;

需要满足以下四个基本要点:

消除重复(被动)。体现了低耦合
分离关注点(主动)。也叫分离不同方向变化,是整个模块化思想的延伸,也就是单一职责和组合复用的表现
缩小依赖范围(主动)。体现高内聚,迪米特法则的表现
依赖于稳定(主动)。耦合点的体现,依赖稳定的接口;是接口分离原则换了一个说法


我们结合上面的四个基本要点来说明

1、消除重复
导致存在重复的原因常有:

低成本(拷贝粘贴)
对于变化的恐惧(另起炉灶)
不易识别(代码混乱)
价值导向(不重视内部质量)
认知差异(不具备敏锐的洞察力)
消除重复有几大分类,处理的策略也不同:

类或方法完全重复:直接删掉重复即可,保留一份复用即可
参数型重复:两个函数的算法相同,只是处理的数据不同,将差异的数据参数化传递即可。
调用型重复:如果两个函数的调用部分完全相同,可以将相同的部分提取为函数F,然后原函数各自对F进行调用。
回调型重复:如果两个函数的回调部分完全相同,可以将相同的部分提取为函数F,将差异的部分形成原型相同的两个函数s1、s2,然后通过F分别对s1、s2进行调用
2、分离关注点
2.1 什么是关注点?
关注点,就是上面所说的耦合点,正交点,那么在软件上我们怎么理解这个关注点呢,就是从一个行为角度去看具备什么功能,我们了解软件上可以做很多分层,就是从这个关注点切入,划分不同层次的功能面,比如有:

应用层:关注点是展示的多样性、交互的体验性
业务层:关注点是业务流程的编排
领域层:关注点是核心业务模型,如何更好的支撑业务
资源层:关注点是数据的存取
这不就是单一职责么,每个层面只关注自己范围内的职责。

2.2 如何分离这些关注点?
小到一个函数,大到一个类,再或者是一个包,甚至更大的是一个层,都可以看作是一个关注点,关注点常见划分的手段有两种:

功能(职责):平时说的边界也是在分离各自己的关注点,划分边界也是体现了单一职责。
业务语义:在领域建模中经常使用到,根据业务语义进行拆分,不同的对象放在不同的域内,如有订单域、商品域、交易域、结算域等等,它们的业务含义是不一样的。
具体如何做:

拆分:如何拆分也可以按照功能和业务语义进行拆分
归类:在拆分的基础上做合并和抽象,哪些要放在一起,哪些是具有层次依赖的,这些最终是要形成一个整体
实现例子:

面向接口编程:接口关注的是能做什么;接口的实现关注的是如何做的问题。
配置文件:把具体的实现写在配置文件里,像数据库的驱动、连接都可以写在配置文件里。只关注有数据库的服务,不关注具体的数据库是什么。
工厂模式:工厂类帮我们管理了对象
默认约定:默认约定大于配置是现在流行的做法,它本质来讲和配置文件没有什么太大的区别。
关注点开放:找出共性的东西作为核心能力,将业务会变的部分开放出去,给业务方自己去做,我们只做核心的功能。可以把变的部分抽象出一个接口出来,具体的实现由业务方去实现,我们要提供的核心能力就是解析出业务方写的代码。在典型的具有模板结构中可以应用此法。
3、缩小依赖范围
尽可能减少依赖点的数量;
依赖点应包含尽可能少的知识;
依赖点也应该高内聚,而不应该强迫依赖方依赖它不需要的东西;
4、依赖于稳定
依赖点越稳定,依赖方受依赖点变化影响的概率越低。

如何让依赖更趋于稳定:

站在需求的角度,而不是实现的角度定义依赖点(API),会让API更加稳定。
需求是不断变化的,必须对需求进行抽象和建模,找出其中共性本质的东西,才能使API更加稳定。