什么是“正交性”?

当谈到编程语言时,“正交性”是什么意思?

正交性的一些例子是什么?

57951 次浏览

来自 维基百科:

计算机科学

正交性是促进复杂设计的可行性和紧凑性的系统设计性质。正交性保证了修改系统组件产生的技术效果既不会产生副作用,也不会将副作用传播到系统的其他组件。一个由组件组成的系统的突发行为应该被其逻辑的形式化定义严格控制,而不是由于不良集成所产生的副作用,即模块和接口的非正交设计。正交性减少了测试和开发时间,因为它更容易验证既不会引起副作用也不依赖于它们的设计。

例如,一辆汽车有正交的部件和控制(例如,加速汽车不影响其他任何东西,只影响与加速功能有关的部件)。另一方面,一个非正交设计可能会影响它的转向制动(例如电子稳定控制) ,或者它的速度调整它的悬挂。因此,这种用法被认为是从数学中的正交使用派生出来的: 一个人可以投影到一个子空间上的一组基向量的每个成员分别投影,并添加投影当且仅当基向量是相互正交的。

如果任何指令可以在任何寻址模式下使用任何寄存器,则称指令集是正交的。这个术语源于将指令看作一个向量,其组成部分是指令字段。一个字段标识要操作的寄存器,另一个字段指定寻址模式。正交指令集对寄存器和寻址模式的所有组合进行唯一编码。

来自 Eric S. Raymond 的 UNIX 编程艺术

正交性是一个最重要的性质,可以帮助使甚至复杂的设计紧凑。在纯正交设计中,操作没有副作用; 每个操作(无论是 API 调用、宏调用还是语言操作)只改变一件事,而不影响其他操作。只有一种方法可以更改您所控制的任何系统的每个属性。

正交性 是指“改变 A 不改变 B”的性质。正交系统的一个例子是收音机,其中改变电台不改变音量,反之亦然。

一个非正交系统就像一架直升机,改变速度可以改变方向。

在编程语言中,这意味着当您执行一条指令时,除了该指令之外什么也不会发生(这对于调试非常重要)。

提到 指令集还有一个特定的含义。

想象一下,它能够改变一件事,而不会对另一件事产生看不见的影响。

来自 维基百科:

正交性是一种系统设计 物业促进可行性及 复杂设计的紧凑性。 正交性保证了这一点 修改技术效果 由系统的一个组成部分产生 既不创造也不传播一方 其他组成部分的影响 系统的紧急行为 由部件组成的系统 被形式严格控制 其逻辑的定义,而不是由 不良副作用 积分,即非正交 模块和接口的设计。 正交性减少了测试和 开发时间,因为它更容易 来验证这两种设计都不会导致 副作用,也不依赖于他们。

例如,一辆汽车有正交 元件及控制器(例如:。 加速的车辆没有 影响其他任何东西 专门涉及的组件 加速度函数) 另一方面,非正交设计 可能会影响它的方向 制动(例如电子稳定性 控制) ,或其速度调整其 因此,这个 用法被认为是从 正交在数学中的应用: 一 可以将向量投射到子空间 通过将其投影到 基向量的集合 当且仅当 基向量是相互的 正交。

一个指令集被称为 如果任何指令可以使用正交 在任何寻址模式下的任何寄存器。 这个术语来自 考虑指令作为向量 其组成部分是指令 一个字段标识 登记册须予操作,以及 另一个指定寻址模式。 唯一正交指令集 对寄存器的所有组合进行编码 和寻址模式。

用最简单的术语来说,如果改变一个对另一个没有影响,那么两个事物就是正交的。

如果您有一组构造。如果一种语言允许程序员自由地混合这些构造,那么这种语言就是 正交。例如,在 C 语言中,你不能返回一个数组(静态数组) ,在这种情况下,C 语言被认为是非正交的:

int[] fun(); // you can't return a static array.
// Of course you can return a pointer, but the langauge allows passing arrays.
// So, it is unorthognal in case.

广义而言,正交性是指两件事物之间的关系,它们对彼此的影响微乎其微。

这个术语来自数学,其中两个向量是正交的,如果它们在直角相交。

考虑一个典型的二维笛卡尔空间(典型的带 X/Y 轴的网格)。绘制两条直线: x = 1和 y = 1。这两条线是正交的。你可以通过改变 x 来改变 x = 1,这对另一行没有影响,反之亦然。

在软件中,这个术语可以适当地用在你所说的系统的两个部分相互独立运行的情况下。

在讨论关于编程语言的项目决策时,正交性可能被认为是多么容易预测关于该语言的其他事情。

例如,在一种语言中,你可以拥有:

Str.Split

用于拆分字符串和

Len (str)

因为长度。

在一种更加正交的语言中,总是使用 str.x 或 x (str)。

当您要克隆一个对象或者做其他事情时,您就会知道是否要使用

克隆(obj)

或者

对象,克隆人

这是编程语言正交性的主要问题之一。这样可以避免你查阅说明书或询问别人。

这篇维基百科文章更多地讨论了复杂设计或低级语言的正交性。 正如上面有人在评论中建议的那样,Sebesta 的书清楚地谈到了正交性。

如果我只使用一个句子,我会说,当一个编程语言的未知部分按照你所看到的那样行事时,它是正交的。 或者... 没有惊喜。

;)

大多数答案都很冗长,甚至晦涩难懂。重点是: 如果一个工具是正交的,那么它可以被添加、替换或者移除,从而有利于更好的工具,而不会把其他事情搞砸。

这就是木匠用锤子和锯子的区别,锤子和锯子可以用来敲打或锯木头,或者用一种新型的锤子和锯子组合来锯木头,然后把它们敲在一起。两种工具都可以用来锯,然后再一起锤,但是如果你的任务需要锯,而不是锤,那么只有正交工具可以用。同样的,如果你需要用螺丝代替锤子,你不需要扔掉你的锯子,如果它是正交的(不是和锤子混在一起的)。

经典的例子是 unix 命令行工具: 您有一个用于获取磁盘内容(dd)的工具,另一个用于过滤文件中的行(grep) ,另一个用于将这些行写入文件(cat) ,等等。这些都可以随意混合和匹配。

在编程语言中,如果一个编程语言特性没有限制(或异常) ,那么这个特性就是正交的。 例如,在 Pascal 中函数不能返回结构化类型。这是对从函数返回值的限制。因此,我们认为它是一个非正交的特征。;)

编程中的正交性:

正交性是一个重要的概念,解决了如何以相对较少的方式组合相对较少的组件,以获得期望的结果。它与简单性相关联; 设计越正交,异常就越少。这使得用编程语言学习、阅读和编写程序变得更加容易。正交特征的意义与上下文无关; 关键参数是对称性和一致性(例如,指针是一个正交概念)。

维基百科

摘自 Robert W. Sebesta 的“编程语言的概念”:

作为高级语言缺乏正交性的例子, 请考虑 C 中的下列规则和异常,尽管 C 有两个 各种结构化数据类型、数组和记录(结构)、记录 可以从函数返回,但数组不能 结构可以是任何数据类型,但 void 或相同的结构除外 数组元素可以是除 void 或函数之外的任何数据类型。 参数是按值传递的,除非它们是数组,在这种情况下 它们实际上是通过引用传递的(因为 在 C 程序中没有下标的数组名称被解释为 数组的第一个元素的地址)

编程语言中的正交性意味着一个相对较小的 原始构造可以通过相对较少的几种方式组合在一起 建立语言的控制和数据结构 基元的可能组合是合法的、有意义的。例如,考虑数据类型。假设一种语言有四种基本数据类型(整数、浮点数、, 和两个类型运算符(数组和指针) 类型运算符可以应用于它们自己和四个基元数据类型, 可以定义大量的数据结构。 正交语言特征的意义独立于 它在程序中出现的上下文。(单词正交来自 数学概念的正交向量,这是独立的每个 正交性遵循的是原始-之间关系的对称性 缺乏正交性会导致语言规则的例外。 例如,在支持指针的编程语言中,它应该是 可以定义指向语言中定义的任何特定类型的指针。 但是,如果不允许指针指向数组,则无法定义许多潜在有用的用户定义数据结构。 通过比较,我们可以说明正交性作为一个设计概念的使用 分析 IBM 大型机汇编语言的一个方面 和 VAX 系列小型计算机。我们考虑一个简单的情况: 添加驻留在内存或寄存器中的两个32位整数值 用和替换两个值中的一个 为此目的的指示,其中有表格

A Reg1, memory_cell
AR Reg1, Reg2

其中 Reg1和 Reg2表示寄存器。这些寄存器的语义是

Reg1 ← contents(Reg1) + contents(memory_cell)
Reg1 ← contents(Reg1) + contents(Reg2)

32位整数值的 VAX 加法指令是

ADDL operand_1, operand_2

其语义是

operand_2 ← contents(operand_1) + contents(operand_2)

在这种情况下,操作数可以是寄存器或内存单元。 VAX 指令设计是正交的,因为单个指令可以 使用寄存器或内存单元格作为操作数 指定操作数,这些操作数可以以所有可能的方式组合 不是正交的。四个操作数组合中只有两个可能是 两者需要不同的指令 A 和 AR 限制较多,因此可写性较低。例如,不能添加 两个值,并将和存储在内存位置 设计是更难学习,因为限制和额外的指令。 正交性与简单性密切相关: 设计一种语言时,语言规则要求的例外越少 异常意味着设计中更高程度的规则性,这使得 更容易学习、阅读和理解的语言。任何学过手语的人 英语的很大一部分可以证明学习英语的困难 许多规则异常(例如,除了 c 之外,e 之前的 i)。

正交性是指语言由一组独立的原语结构组成的程度,这些原语结构可以根据需要组合起来表达程序。 如果没有关于如何组合它们的限制,那么特性是正交的

Example : non-orthogonality

函数不能返回结构化类型。 函数式语言是高度正交的。

正交性的基本思想是,概念上不相关的事物在系统中不应该相关。架构中真正与其他部分无关的部分,例如数据库和 UI,不应该一起进行更改。对其中一个的改变不应该导致对另一个的改变。

编程语言中正交性的实际例子

有许多答案已经解释了什么是一般的正交性,同时指定了一些虚构的例子。例如 这个答案很好地解释了它。我想提供(并收集)一些编程语言中正交或非正交特性的真实例子:

正交: C + + 20模块和命名空间

C + + 20中的 关于新模块系统的页面是这样写的:

模块与 命名空间正交

在这种情况下,他们写道模块与名称空间是正交的,因为像 import foo这样的语句不会导入与 foo相关的模块名称空间:

import foo;            // foo exports foo::bar()
bar ();                // Error
foo::bar ();           // Ok
using namespace foo;
bar ();                // Ok

(改编自 模块 -cppcon2017幻灯片9)

正交性是指概念上不相关的东西在系统中不应该相关,所以架构中不相关的部分,比如数据库和 UI 不应该一起更改。对系统某一部分的更改不应导致对另一部分的更改。

例如,如果您更改了屏幕上的几行,并导致数据库模式发生更改,则称为耦合。您通常希望尽量减少几乎不相关的事情之间的耦合,因为它可能会增长,从长远来看,维护系统可能会成为一场噩梦。

摘自迈克尔 · C · 费瑟斯的著作《有效使用遗留代码》 :

如果您想要改变代码中现有的行为,并且只有一个地方需要进行改变,那么您就得到了正交性。