1

虽然 SOLID 设计原则主要应用于面向对象的系统,但也有一些 SOLID 概念可以应用于过程式编程,例如 SRP 或 DIP。但是当我研究 POSIX API 中可用的一些函数时,我注意到有些原则没有得到尊重,即使它可能是这样。

我将以SRP和系统调用sigaction为例:

  • SRP指出,在我们的例子中,一个函数必须有一个单一的职责,这意味着我们系统规范的单个部分的变化是可能改变函数规范的一件事。
  • sigaction是一个系统调用,用于更改进程在接收到信号时所采取的操作。

sigaction可用于安装以下形式的基本处理程序:

void (*sa_handler)(int)

这意味着处理程序仅接收信号的编号以执行其操作。系统调用也可用于安装以下形式的处理程序:

void (*sa_sigaction)(int, siginfo_t*, void*)

这让我们获得了有关处理信号的更多信息。由于调用者放置了标志,两种形式都安装了相同的系统调用。

在我看来,sigaction违反了SRP原则,因为它有责任实现这两种类型的处理程序安装。

所以我的问题是:POSIX API 是否违反了 SOLID 原则,如果是,为什么?

4

4 回答 4

1

除了这些原则是意见问题之外,POSIX 比 SOLID 早了几十年。它还主要记录和规范现有实践,而不是从头开始重新发明事物。与违反 SRP 之类的迂腐做法相比,由委员会设计往往是一个更大的问题,因此这几乎可以肯定是一件好事。

请注意,POSIX 实际设计的一些接口确实非常遵循 OOP 设计原则,通常以引入缺陷的方式。例如,由于它依赖于属性对象的创建,它posix_spawn未能成为 AS 安全的替代品。POSIX 线程接口也从 OOP 中大量借用,这些方式通常不会破坏任何东西,但会使它们无缘无故地使用起来很痛苦。forkexecve

于 2018-01-19T13:32:27.790 回答
1

我们对您调用的 sa_sigaction 的特定实现的目的(即单一职责)一无所知。

但是,如果我不得不猜测,我希望 sa_sigaction 实现是接口模块的一部分,该接口模块在较低级别的操作系统特定功能之上实现了 POSIX API,并且 sa_sigaction 函数的一项职责是实现POSIX 规范的特定部分。

换句话说,它是一个适配器模式对象,它有一个单一的职责。

也许您的意思是说 POSIX API 规范违反了 SRP……也许但这并不重要。SRP 是为了让您的系统能够适应不断变化的需求。作为一个古老的 API 标准,POSIX 并没有得到很多新的要求。它基本上记录了过去的事情是如何完成的,历史事实不会改变。

于 2018-01-20T19:32:40.710 回答
1

POSIX API 是否违反 SOLID 原则?

的。POSIX 已有数十年的历史,由许多软件工程师在 IEEE 的支持下编写。SOLID 相对较新(相比之下),是由某个名叫 Bob 的人编写的。

POSIX 更加成熟,它背后的人意识到,有简洁的小首字母缩略词(即 SOLID)并不能解释软件工程中的所有小例外。

如果你问我,SOLID 是违反 POSIX 的。

于 2018-02-02T21:00:45.693 回答
0

恕我直言,我认为您的示例如履薄冰(它也忽略了 SOLID 中的 D)。

POSIX 可能违反了 SOLID 原则(也可能不违反)......但另一方面,POSIX 对什么可以分离和什么属于一起有成熟的理解(来自实际使用的理解)。

换句话说,问题是关于“什么是单一职责?”的范围,而 POSIX 拥有数十年的经验来帮助它划清界限。

在您的示例中,您声明sigaction必须实现这两种类型的东西,但这是一个谬误。

sigaction有一个单一的责任 - 它需要注册一个回调。回调类型实际上无关紧要,因为责任在于“注册”。

如果一个 Arraypush函数与类型无关,它会违反 SRP 原则吗?不,它会处理一个单一的责任 - 推送到数组。同样在这里。

如果我按照你的逻辑,为每个回调类型实现不同的函数,我会发现自己一遍又一遍地编写相同的代码,但有细微的变化——这违反了 DRY 原则,这清楚地表明这些函数共享相同的责任,应该统一。

于 2018-02-03T15:51:41.193 回答