免责声明:我将为此答案排除 Typescript,仅讨论动态 javascript
Node js 是一种解释型语言,没有编译,所以它的运行时不同于 Java、C# 等编译型语言。
另一个非常重要的区别是 javascript 是一种弱类型语言,因此您会遇到的大多数错误都发生在运行时,这与编译后的强类型语言不同。
编译的强类型语言需要了解你使用的是什么(类、接口、方法参数等),以及它在编译时的样子。
动态脚本语言没有这个问题。在那里,你看到的是 runtime 检查你调用的东西(例如一个函数),如果它不存在就会抛出一个错误。
话虽如此,在 Node 中,您进行更改时不必重新编译应用程序,但您确实需要重新部署新的更改。
在编译语言中,您确实需要重新编译受更改影响的应用程序的某个部分,并且您还部署了该更改,因此两者都需要重新部署,但这个也需要重新编译。
通常,这些应用程序被分成单独的二进制文件,有些是库,有些是可执行文件,因此您只需重新编译二进制文件的子集。
在编译语言和解释语言中,当您更改代码的一部分时,依赖它的其他部分将受到更改的影响。现在你想要的是将受影响的代码部分最小化。
当您重新部署时,您确实需要重新启动正在执行您的应用程序的进程。在 Node 中,您需要重新启动它才能开始运行您的新代码。
在编译语言中,您需要重新启动可执行文件,以便它运行您的新代码,所以它几乎相同。
解释型和编译型语言都具有动态加载库 (dll) 或 javascript 模块的机制,它们只是文本文件,因此无需重新启动进程。
仅仅因为您在 Javascript 中没有像在 Java 或 C# 中那样的显式接口,并不意味着您没有绑定和依赖接口。如果您的代码调用对象上的函数,则此代码预计该函数将存在,因此它是对象接口的一部分。您可以更改此函数的实现,而无需更改调用代码,因为它取决于函数的名称和参数,而不是实现。
依赖倒置也可以应用于Node,只是你有隐式接口而不是显式定义的接口。您只需要从抽象的角度进行思考,并以不受任何实现细节约束的方式定义接口。
如果更改接口,实现和客户端代码都会受到影响。如果仅更改实现,则接口的客户端不受影响。这适用于弱类型和强类型语言,无论这发生在编译时的运行时。
是否需要重新编译是特定于语言的,是否可以在不必重新启动进程的情况下进行重新部署是另一回事。最大的问题是“你要改变什么,接口还是实现?”
您提供的数据库示例需要有关更改内容的更多详细信息。您的架构可能会更改而不会影响接口,只会影响实现。它可能会发生变化,因为应用程序的其余部分发生了重大变化,这会影响它的某些部分。
如果您只更改实现,而不更改接口(函数名称、定义等),您只更改 DB 模块,因此不影响更高级别的代码。依赖倒置有效,高层代码不受影响。
确实,使用具有显式接口的 C# 和 Java 语言更容易理解它,并且还有另一个步骤,涉及编译。很难想象 javascript 中的 隐式接口 是一样的,但在抽象层面上是一样的,只是机制不同。在这两种类型的语言中,如果您更改界面,代码中断,就差不多了。
这就是为什么您应该定义抽象和接口并控制对它们的更改,这样您的代码就不会中断。当然接口也需要改变。当他们这样做时,您需要更新客户端代码。这也适用于这两种语言。