1.6 函数式编程的好处
上一节展示了如何使用HOFs来避免重复,并实现更好的关注点分离。事实上,FP的优势之一就是它的简洁性:你可以用更少的代码行实现同样的结果。将其乘以一个典型应用中的数万行代码,简洁性对应用的可维护性也有积极的影响。
通过应用你在本书中学到的功能技术,还有很多好处,它们大致可分为三类:
- 更干净的代码 —— 除了前面提到的简洁性之外,FP还能使代码更有表现力,更易读,更易测试。 整洁的代码不仅是开发人员的智力享受,而且还能通过减少维护成本为企业带来巨大的经济效益。
- 更好地支持并发性 —— 从多核CPU到分布式系统等几个因素,给你的应用程序带来了高度的并发性。并发在传统上与一些棘手的问题有关,如死锁、丢失更新等;FP提供的技术可以防止这些问题的发生。你会在第2章看到一个介绍性的例子,在本书的最后会看到更高级的例子。
- 多范式方法 —— 他们说,如果你唯一的工具是一把锤子,每一个问题看起来都像一颗钉子。相反,你能从越多的角度来看待一个特定的问题,你就越有可能找到一个最佳的解决方案。如果你已经熟练掌握了OOP,学习不同的范式,如FP,将不可避免地给你带来更丰富的视角。 当面临一个问题时,你将能够考虑几种方法并选择最有效的。
练习
我建议你花时间做这些练习,并顺便想出一些自己的想法。 GitHub上的代码样本库(https://github.com/la-yumba/functional-csharp-code)包括占位符,这样你就可以用最少的设置工作编写、编译和运行你的代码。它还包括一些解决方案,你可以对照这些解决方案检查你的结果:
- 浏览 System.Linq.Enumerable (https://docs.microsoft.com/en-us/dotnet/api/system.linq.enumerable) 的方法。哪些是 HOF?你认为哪个意味着给定函数的迭代应用?
- 编写一个否定给定谓词的函数:只要给定的谓词评价为真,结果函数评价为假,反之亦然。
- 编写一个使用快速排序对 List< int > 进行排序的方法(返回一个新列表,而不是原地排序)。
- 将之前的实现概括为一个 List< T > 和一个 Comparison< T > 委托。
- 在本章中,你已经看到了一个 Using 函数,它接受一个 IDisposable 和一个 Func<TDisp,R> 类型的函数。编写使用 aFunc< IDisposable > 作为第一个参数而不是 IDisposable 的重载。 (这可用于避免某些代码分析工具引发关于实例化 IDisposable 而不是处置它的警告。)
总结
- FP是一个强大的范式,可以帮助你使你的代码更加简洁、可维护、有表现力、健壮、可测试和并发友好。
- FP与OOP的不同之处在于,它关注的是函数而不是对象,是数据转换而不是状态突变。
- FP可以被看作是一个基于两个基本原理的技术集合:
- 函数式第一公民
- 应避免就地更新
- C# 中的函数可以用方法、委托和 lambda 来表示。
- FP利用高阶函数(将其他函数作为输入或输出的函数);因此,语言必须将函数作为第一公民。