SOLID 原则适用于函数式编程吗?

2025-06-07

SOLID 原则适用于函数式编程吗?

如果您有兴趣阅读西班牙语版的这篇文章🇪🇸,请查看我的博客:
The Developer's Dungeon

昨天,我浏览一个我经常去的在线开发者社区,发现那里正在就如何编写优秀的代码展开一场激烈的辩论。像往常一样,设计模式代码整洁之道SOLID 等术语被抛在一边,引发了一场激烈的编程术语之争。很明显,听众主要是面向对象程序员。突然,有人开始谈论函数式编程,作为一个正在努力从函数式编程方法中汲取最大潜能的面向对象程序员,我被深深地吸引了。

该人认为 SOLID 和设计模式是面向对象编程 (OOP) 的东西,它们与函数式编程 (FP) 关系不太好。

这个论点一直萦绕在我的脑海里,所以我决定写篇文章来表达我的个人观点。由于我对 SOLID 和设计模式有两种不同的看法,所以今天我只讨论 SOLID,不过不久的将来我可能会讨论设计模式。

让我们先做一些介绍。


什么是 SOLID?

SOLID 是五项设计原则的助记缩写,旨在使软件设计更易于理解、灵活和维护

它们是由 Robert C. Martin 于 21 世纪初在他的论文《设计原则和
设计模式》
中首次提出的,具体如下:

  • 单一职责原则

  • 开放封闭原则

  • 里氏替换原则

  • 接口隔离原则

  • 依赖倒置原则

它们在 OOP 和 FP 中如何使用?

让我们逐一看看它们如何应用于这两种范式。

单一职责原则

“一个对象应该只有一个职责,也就是说,只有对软件规范的一部分的改变才能够影响该对象的规范。”

传统上,当人们谈论这个原则时,他们会想到类(尽管其最初的想法来自 UNIX 开发),他们会考虑将行为提取到多个类中,并处理适当的关注点分离。
虽然函数式编程语言没有类,但同样的原则仍然适用。函数应该是可重用的小代码片段,你可以自由地组合它们来创建复杂的行为。

这可以提取到几乎任何东西,一旦你的功能很小,它们所在的模块也应该形成一个内聚的闭包,只做一件事并且做得很好。

只要您的函数、类或模块只有一个改变的理由,那么您就应用了这个原则。

开放封闭原则

“软件实体……应该对扩展开放,但对修改关闭。”

这个原则通常与继承直接相关。一个定义明确的父类包含功能,并且该类的子类可以扩展或重用所提到的功能。实际上,它只是意味着我们应该能够重用和扩展代码,而无需修改原始实现。

函数式编程不使用继承,而是通过两种工具来实现这一点。组合用于从先前定义的函数创建新的行为,而高阶函数用于在运行时更改功能。顺便说一句,如果您有兴趣阅读更多关于这些主题的内容,可以查看我的系列文章《面向对象开发人员的函数式编程》

里氏替换原则

“程序中的对象应该可以用其子类型的实例替换,而不会改变该程序的正确性。”

同样,当人们普遍思考这个原则时,他们首先想到的是,如果父类具有某些行为,则其子类不应该破坏该行为,但这不是唯一适用的情况,LSP 也适用于我们使用通用或参数编程的情况,我们创建适用于各种类型的函数,它们都具有使它们可以互换的共同真理。

这种模式在函数式编程中非常常见,在函数式编程中,您可以创建包含多态类型(又称泛型)的函数,以确保一组输入可以无缝地替换为另一组输入,而无需对底层代码进行任何更改。

接口隔离原则

“许多特定于客户端的接口比一个通用接口更好。”

这是一个简单的问题,但是很多人,包括那些引起我注意这个话题的人,都过于执着于“接口”这个词,他们会自动参考 C# 或 Java 等语言中的接口概念,他们认为如果没有接口,那么这个原则就无法应用。

实际上,组件之间的所有交互都是通过接口完成的。当你使用模块中的函数时,你实际上是在使用该模块的已释放接口。即使我们使用的是动态类型语言,该接口仍然存在。这样做的目的是,创建模块(或类、接口、API 等等)的方式需要具有内聚性,你应该提供一种清晰的实现方式,而不是多种,并且应该只公开用户执行特定任务所需的内容。

依赖倒置原则

“人们应该依赖抽象,而不是具体。”

在 C# 等语言中,这可以通过两种工具实现。一种是创建接口来定义预定义功能的契约。另一种是使用依赖注入,这样该功能的用户无需手动实例化具体类,而是通过构造函数接收接口的实例,然后只需调用实例上的相应方法即可。

在函数式编程中,抽象是处理代码的默认方式,函数也是抽象的,尤其是在函数式编程中,我们更关心数​​据的“形状”,而不是它们所依附的具体类型。这使得我们可以在运行时自由地更改实现,方法是将函数作为参数传递给其他函数,甚至将函数作为计算结果返回。


希望你喜欢我对 SOLID 和函数式编程的解读。如果你想直接比较 OOP 和 FP 中设计模式的实现,请在下方评论区留言。

与往常一样,如果您喜欢这篇文章,请在社交媒体上分享。

文章来源:https://dev.to/patferraggi/do-the-solid-principles-apply-to-functional-programming-56lm
PREV
函数式编程中需要设计模式吗?
NEXT
你确定你是一名专业开发人员吗?