diff --git a/zh-CN/cookbook/design/disposable.md b/zh-CN/cookbook/design/disposable.md index e809581a7533..03f8fa0c8725 100644 --- a/zh-CN/cookbook/design/disposable.md +++ b/zh-CN/cookbook/design/disposable.md @@ -31,7 +31,7 @@ Cordis 的名字来源于拉丁语的心。我希望它能成为未来软件 ( **可逆性 (Disposability)**,即回收资源的能力,可以为软件带来以下好处: -**可组合性 (Composibility)**。很多软件很喜欢用「模块化」「插件」这样的词,这显然是来自现实世界的概念。然而现实中的模块也应当是可拆卸的,现实中的插件也应当是可以拔出的。不可逆的软件即便进行了模块化,也只会随着时间推移而变得更加臃肿。此外,可逆性可以让我们更好地理解模块之间的依赖关系,从而更好地促成解耦。这一点我们稍后会进一步讨论。 +**可组合性 (Composibility)**。很多软件很喜欢用「模块化」「插件」这样的词,这显然是来自现实世界的概念。然而现实中的模块也应当是可拆卸的,现实中的插件也应当是可以拔出的。不可逆的软件即便进行了模块化,也只会随着时间推移而变得更加臃肿。此外,可逆性可以让我们更好地理解模块之间的依赖关系,从而更好地促成解耦。这一点我们 [稍后](#compose) 会进一步讨论。 **可靠性 (Reliability)**。当软件的规模增加时,可逆性可以确保软件所使用的内存和其他资源都在可控范围内 (内存安全其实是资源安全的一种特殊情况)。同时,由于可逆性也意味着可追踪性,即便某个模块出现了资源泄露,我们也可以快速定位错误的来源。 @@ -202,3 +202,21 @@ $$ 在 Cordis 中,插件之间默认情况下不存在先后关系。换句话说,默认任何两个插件的执行顺序都是可以交换的。如果你想要表达插件之间的依赖关系,则需要通过 **服务 (Service)** 来实现。服务用一个字符串表示,可以被插件提供 (provide) 或注入 (inject)。 Cordis 通过其自身的机制确保提供任何一对提供 / 注入同名服务的插件的生命周期都是包含关系。此外,Cordis 还提供了服务隔离的概念,开发者可以为任何一个服务名称创建隔离上下文,使其内部和外部的插件对于该服务名称无法相互感知和访问。 + +## 尾声:可组合性的本质 {#compose} + +很多人谈论可组合性,主要说的是解耦,也就是将代码拆解到不同函数、不同模块的能力。但其实我们编写的代码并不是静态的,可组合性可以在更多的维度上定义: + +- 逻辑可组合性:代码自身的解耦能力 (常见的理解方式)。 +- 时间可组合性:代码可以被同时加载、可以被回收副作用的能力 (本文主要介绍的部分)。 +- 空间可组合性:代码之间能够有效声明和隔离依赖关系的能力。 + +我希望借助 Cordis 这个框架,勾勒出软件文明的一个未来。在这个未来,人们可以按照需求背后的本质逻辑,组合出高效、可靠、易于开发和维护的软件。 + +## 畅想:在语言层面确保资源安全 + +Rust 声称自己在语言层面确保了内存安全 (具体是不是这里不做讨论),那么 Cordis 能否在确保资源安全呢?很遗憾,目前并不能。开发者只需设置几个全局变量、或者调用一些未被封装过的 API,就可以绕过 Cordis 的保护机制。但这并不意味着 Cordis 是无用的。如果未来我们将所有的底层 API 都封装起来,并确保用户只能通过上下文调用,那么 Cordis 就可以确保资源安全了。 + +一种更好的思路是直接从语言层面加以设计。例如可以将全局变量的访问和一些底层 API 视为“不安全”的,那么一个不含 `unsafe` 关键字的代码片段就可以被证明资源安全的了。我们还可以在编译期间检查出所有的资源安全问题,而不需要等到运行时才发现。少数函数式编程语言实现了 Algebric Effects,可以实现类似资源安全的概念。不过受限于函数式语言本身的特性,要让主流的软件开发者接受这种编程范式还需要很长的时间。 + +相比较而言,Cordis 在设计上能够与主流的 OOP 语言完美结合,并且不需要重构整套系统。任何特定领域的框架都可以通过 Cordis 来实现可逆性,而对应领域的插件开发者也可以在不了解任何数学知识的情况下编写可逆的插件。这种渐进性是 Cordis 的一大优势。