编程范式(三):函数式编程

简介: 编程范式(三):函数式编程

背景介绍


上一篇文章我们一起学习了面向对象编程,这一篇文章我们就一起学习函数式编程吧~

《架构整洁之道》系列:



函数式编程


函数式编程所依赖的原理,在很多方面其实是早于编程本身出现的。因为函数式编程这种范式强烈依赖于 Alonzo Church 在 20 世纪 30 年代发明的 λ 演算。


函数式编程语言中的变量(variable)是不可变(Vary) 的。


书中多次提到 Clojure 语言作为函数式编程的范例,大家如果感兴趣可以对其进行了解。


不可变性与软件架构


为什么不可变性是软件架构设计需要考虑的重点呢?为什么软件架构师要操心变量的可变性呢?


所有的竞争问题、死锁问题、并发更新问题都是由可变变量导致的。如果变量永远不会被更改,那就不可能产生竞争或者并发更新问题。如果锁状态是不可变的,那就永远不会产生死锁问题。

换句话说,一切并发应用遇到的问题,一切由于使用多线程、多处理器而引起的问题,如果没有可变变量的话都不可能发生。


我们需要确保自己设计的系统在多线程、多处理器环境中能稳定工作。所以在这里,我们实际应该要问的问题是: 不可变性是否实际可行?


如果我们能忽略存储器与处理器在速度上的限制,那么答案是肯定的。否则的话,不可变性只有在一定情况下是可行的。


下面让我们来看一下它具体该如何做到可行。


可变性隔离


一种常见方式是将应用程序,或者是应用程序的内部服务进行切分,划分为可变的和不可变的两种组件。不可变组件用纯函数的方式来执行任务,期间不更改任何状态。这些不可变的组件将通过与 一个或多个非函数式组件通信的方式来修改变量状态。


网络异常,图片无法展示
|


由于状态的修改会导致一系列并发问题的产生,所以我们通常会采用某种事务型内存来保护可变变量,避免同步更新和竞争状态的发生。


一个架构设计良好的应用程序应该将状态修改的部分和不需要修改状态的部分隔离成单独的组件,然后用合适的机制来保护可变量。软件架构师应该着力于将大部分处理逻辑都归于不可变组件中,可变状态组件的逻辑应该越少越好。


事件溯源

举个例子:


假设某个银行应用程序需要维护客户账户余额信息,当它执行存取款事务时,就要同时负责修改余额记录。但是如果我们不保存具体账户余额,仅仅保存事务日志,那么当有人想查询账户余额时,我们就将全部交易记录取出,并且每次都得从最开始到当下进行累计。当然,这样的设计就不需要维护任何可变变量了。


这就是事件溯源,在这种体系下,我们只存储事务记录,不存储具体状态。当需要具体状态时,我们只要从头开始计算所有的事务即可。


这种数据存储模式中不存在删除和更新的情况,我们的应用程序不是 CRUD,而是 CR。因为更新和删除这两种操作都不存在了,自然也就不存在并发问题。


如果我们有足够大的存储量和处理能力,应用程序就可以用完全不可变的、纯函数式的方式来编程。「什么叫足够大?即整个程序的生命周期内,我们有足够的存储和处理能力来满足它。」


结束语


网络异常,图片无法展示
|


三种编程范式到这里就一起学习完成了,下面我们进行总结:


  • 结构化编程是对程序控制权的直接转移的限制。
  • 面向对象编程是对程序控制权的间接转移的限制。
  • 函数式编程是对程序中赋值操作的限制。


这三个编程范式都对程序员提出了新的限制。每个范式都约束了某种编写代码的方式,没有一个编程范式是在增加新能力。


也就是说,我们过去几十年学到的东西主要是什么不应该做。


总而言之,软件,或者说计算机程序无一例外是由顺序结构、分支结构、循环结构和间接转移这几种行为组合而成的,无可增加,也缺一不可。


最后


✨✨✨✨✨✨✨✨✨✨✨✨✨✨✨

少年向来不识天高地厚
放眼处皆自负才高八斗
虽是自命风流
倒也坦诚无忧
我爱这样的少年
谦和而狂妄
骄傲又坦然☀️

✨✨✨✨✨✨✨✨✨✨✨✨✨✨✨

相关文章
|
6月前
|
并行计算 数据处理 UED
探索程序设计范式:面向对象编程与函数式编程之辩
在现代软件开发中,面向对象编程(OOP)和函数式编程(FP)是两种主流的程序设计范式。本文将对它们进行比较和分析,并探讨如何根据项目需求和个人喜好做出选择。无论是OOP的灵活性和可维护性,还是FP的简洁性和并发性,都有其独特的优势。
|
1月前
|
算法 JavaScript 前端开发
程序员需要掌握的 5种编程范式!
本文介绍了编程范式的基本概念及其重要性,详细解析了命令式编程与声明式编程两种主要范式。命令式编程包括面向过程与面向对象编程,强调逐步执行与模块化;声明式编程涵盖函数式、逻辑及响应式编程,注重描述目标而非具体步骤。通过对比各种范式的优缺点及示例代码,帮助读者理解不同场景下的适用性。
26 2
|
6月前
|
Rust 并行计算 JavaScript
函数式编程:革命性的编程范式
函数式编程:革命性的编程范式
|
6月前
|
大数据 开发者
探索编程范式:面向对象与函数式的抉择
在当今快速发展的软件开发领域,面向对象编程(OOP)和函数式编程(FP)是两种重要的编程范式。本文将深入比较这两种范式的特点、应用场景和优劣势,为读者提供选择时的参考,并探讨如何在实际项目中灵活运用它们。
|
6月前
|
并行计算 数据处理 开发者
Python函数式编程:探索优雅的编程范式
传统的编程范式中,命令式编程和面向对象编程占据主导地位。然而,Python函数式编程作为一种新颖而强大的范式,通过引入函数作为一等公民和不可变性等特性,为开发者提供了更加优雅和灵活的编码方式。本文将深入探讨Python函数式编程的概念与应用,包括高阶函数、纯函数、惰性计算以及函数式编程在并行处理和数据处理方面的实际应用。
|
6月前
|
Java 程序员 数据处理
探索编程范式:面向对象编程与函数式编程的比较与取舍
本文将探讨面向对象编程(OOP)和函数式编程(FP)两种主流的编程范式,并比较它们在代码组织、可复用性、并发性和代码风格等方面的特点。通过深入了解它们的优势和不足,读者可以更好地选择适合自己项目需求的编程范式。
254 1
|
SQL 存储 安全
程序员必须要知道的编程范式,你掌握了吗?
本文给大家介绍了什么是"编程范式",选择合适的编程范式可以提高代码的可读性、可维护性和可扩展性。
33405 42
|
设计模式 分布式计算 算法
聊聊编程范式
聊聊编程范式
聊聊编程范式
|
Java Scala 开发者
函数式编程几个重要概念|学习笔记
快速学习函数式编程几个重要概念。
函数式编程几个重要概念|学习笔记
|
算法 Java Scala
函数式编程基础介绍|学习笔记
快速学习函数式编程基础介绍。
函数式编程基础介绍|学习笔记