http://tommwq.tech/blog/2020/11/19/223

1 软件开发中的正交性

在几何学中,“正交”一词可以简单的理解为“垂直”。软件工程借用了这个术语,用来表示两个软件模块的耦合程度低。正交性高的软件更加灵活、更易于扩展和修改,拥有更长的生命周期、和更低的维护成本。

如果两个对象相互感知(关联、依赖)到对方,二者之间就发生了耦合。正交性就是低耦合性。当一个模块发生变更,与其耦合的模块也需要进行调整,以适配变更。正交性低的软件,需要适配的模块越多。即使一个很小的需求变化,也可能引发大量的代码修改。对于软件来说,修改意味着成本和(引入缺陷的)风险。如果放任成本和风险持续上涨,软件项目很快会变得无法推进,即无法应对需求变化,也无法修补缺陷。因此为了维持软件的竞争力,需要提高正交性。

2 单一职责原则

提高正交性的根本方式就是时刻遵循单一职责原则。

There should never be more than one reason for a class to change.

Single Responsibility Principle

我们从一个例子来理解单一职责原则。

Listing 1: 违反单一职责原则

public class Printer {public void print(String message) { /* ... */ }public void print(String fmt, Object object) {print(format(fmt, object));}public String format(String fmt, Object object) { /* ... */ }
}

如果软件需要支持一种新的打印格式,Printer.format方法就要发生改变。如果软件需要支持一种新的打印设备,Printer.print方法也要发生改变。有两个原因会引发Printer类的改变,这是因为Printer类承担了打印和格式化两个职责。如果采用单一职责原则,应当将打印和格式化职责分离。

Listing 2: 遵守单一职责原则

public class Formatter {public String format(String fmt, Object object) { /* ... */ }
}public class Printer {public void print(String message) { /* ... */ }public void print(String fmt, Object object) {Formatter formatter = new Formatter();print(formatter.format(fmt, object));}
}

3 应用单一职责原则

3.1 分离接口定义和接口实现职责(面向接口编程)

这是单一职责原则最简单也是最常见的应用。

3.2 分离(类层面的)读写职责

这里提到的,不是持久层(数据库)的读写分离,而是在类层面,将读操作和写操作分离。这么做的好处有语义更清晰、读接口是幂等的、以及可以避免不必要的写操作。

Listing 3: 未分离读写接口

public class Calculator {public int add(int value) { ... }
}

Listing 4: 分离读写接口

public class Calculator {public int add(int value) { ... }public int getResult() { ... }
}

3.3 分离类的创建和使用(依赖注入)

Listing 5: 未分离创建和使用

public class Printer {public void print(String message) { /* ... */ }public void print(String fmt, Object object) {Formatter formatter = new Formatter();print(formatter.format(fmt, object));}
}

Listing 6: 分离创建和使用

public class Printer {public Printer(Formatter formatter) {this.formatter = formatter;}public void print(String message) { /* ... */ }public void print(String fmt, Object object) {print(formatter.format(fmt, object));}
}

3.4 分离业务模型、控制模型和试图模型(MVC、MVVM、MVP)

参考

MVC、MVP和MVVM - tommwq.tech/blog

4 如何度量正交性

目前没有很好的度量正交性的方法。考虑到正交性意味着低耦合度,而耦合度是软件模块之间的感知程度,我们可以用下面的公式来描述正交性:

orthogonality = n*(n-1)/k

其中n是软件中模块的数量,k是模块之间依赖关系的数量。如果k=0,我们将正交性定义为正无穷大。

假设软件包含n个模块,这些模块按照依赖关系构成了一个有向图。当每个模块都依赖于其他模块时,依赖关系数量最多,是n*(n-1)个。当各模块互不依赖时,依赖关系数量是0。我们用k表示模块依赖关系数量,显然k衡量了模块之间的耦合度。k的值域依赖于模块数n,我们对k做归一化处理,让k除以n*(n-1),就得到了值域是[0,1]的耦合度度量函数。考虑到正交性和耦合度呈类似反比例的关系,再取倒数就得到了上面的公式。

正交性的好处和实现方法相关推荐

  1. php异常处理的好处,php异常处理方法是什么

    一.异常处理 意外,是在程序运行过程中发生的意料这外的事,使用异常改变脚本正常流程. 相关推荐:<PHP入门教程>if(){ }else{ } try { }catch(异常对象){ } ...

  2. java8 方法引用好处_Java 8方法引用

    原标题:Java 8方法引用 方法引用有助于通过名称指向方法.使用"::"符号描述方法引用.方法引用可以用来指出以下类型的方法 - 静态方法 实例方法 使用new运算符的构造函数( ...

  3. 云渲染是什么?云渲染好处以及安装方法。

    什么是云渲染? 云渲染是基于云服务器针对渲染行业提出的应用解决方案-通过一键提交文件传输至云端,帮助本地解决渲染问题. ​简而言之就是建模软件,例如 3D MAX 建好模型后通过软件上传到云端,利用云 ...

  4. 技术方案设计的方法论及案例分享

    作者 | 高福来(不拔) 来源|阿里巴巴云原生公众号 怎么去体现技术方案设计的深度是大家普遍关心的一个问题,这个问题不是个例问题,因此本文主要分享下作者个人的一些观点和看法. 文章主要分为三个部分: ...

  5. Java中abstract类和abstract方法的相关问题

    当知道一个类的子类将不同的实现某个方法时,把该类声明为抽象类很有用,可以共用相同的父类方法,不必再定义. 抽象类和抽象方法的关系:含有抽象方法的类一定是抽象类,抽象类里不一定含有抽象方法. 抽象类存在 ...

  6. 反思前进路上碰到困难时 应有的应对方法

    碰到困难时  我现有状态的问题 1.会害怕  担心自己解决不了  毕竟未知哈!会出现消极情绪,消极会引起懒惰,懒惰会引起效率低下,进度缓慢! 2.心情烦躁  想远离困难  正常的情绪反应!但是对事情的 ...

  7. java中的规范是什么意思_Java中的异常规范有什么好处?

    我从C来到Java. 在Java和C中,我们都可以指定异常.看起来像这样: void function_name() throw(Exception) { ... if (error) { throw ...

  8. JAVA不同类型数组重载_JAVA补课-DAY1:方法重载和数组

    IDEA简单方法使用 快捷键 Ctrl+Alt+L,IDEA代码格式化 Ctrl+/单行注释,重复按取消 Ctrl+Shift+/多行注释,重复可取消 5.fori<==>for (int ...

  9. 设计模式之六:工厂方法模式(Factory method Pattern)

    工厂方法(Factory Method)模式就是定义一个创建对象的工厂接口,将实际创建工作推迟到子类当中. 核心工厂类不再负责具体产品的创建,仅提供了具体工厂子类必须实现的接口,这样核心类成为一个抽象 ...

  10. 内置方法和模块的应用

    一 . 内置方法 1.__del__   析构方法   释放一个空间之前执行  某对象借用了操作系统的资源,还要通过析构方法归还回去 : 文件资源 网络资源 class File():# 处理文件的d ...

最新文章

  1. bat脚本登陆ftp服务器
  2. chrome浏览器font-size12px无效解决办法
  3. 网站的高性能架构--web前端优化
  4. Programe_Of_Beauty :3.9 重建二叉树
  5. why xml sucks
  6. Syntax error, parameterized types are only available if source level is 1.5
  7. Python的MySQLdb模块安装
  8. NET问答: String 和 string 到底有什么区别?
  9. Gartner:容器采用将迅速增长,但不会很快有利可图
  10. Python面向对象的基本实现
  11. window安装python报错_win10下Python安装pycrypto报错
  12. oracle如何增加磁盘,牛刀小试Oracle之ORACLE 11GR2 RAC安装配置-asm磁盘组配置添加(四)...
  13. 相同java代码,编译生成class文件不同的原因-JDK版本不同(大版本相同,小版本不同)
  14. 个人对游戏加速器行业看法(一):概念介绍
  15. Wget下载网页与镜像网站
  16. JS页面跳转页面大全
  17. 听说某琳系统停止更新了,其他的主机管理系统哪个好?
  18. QT+VS开发界面入门(qt界面在VS2022实现自动生成槽函数)
  19. kaka启动出现:Java HotSpot(TM) 64-Bit Server VM warning: INFO: os::commit_memory(0x00000c00000, 1073,0)
  20. (一)NanoPi m4v2 安装 Home Assistant(含 supervisor)

热门文章

  1. 用PS合并RGB图片和只有透明通道的图片
  2. python 结构体数组的正确初始化方法
  3. 简体与繁体的相互转换
  4. linux用cat建文件,如何使用Linux cat命令
  5. Excel选择下拉匹配
  6. 什么是ROE、ROA和ROS?衡量企业盈利能力的比率有哪些?
  7. 《智能时代》读书笔记:这是最好的时代,也是最坏的时代
  8. 4G通信简单验证(合宙Air720H)
  9. 编译报错【error】dexpreopt.sh:23 exited with status 1
  10. Python实现多个Excel文件合并到一个文件中