模式词汇表1
替代面向对象模式
这一部分会向你展示如何采用函数式语言的特性来替代普通的面向对象模式。这样做通常可以减少我们需要编写的代码数量,从而让我们维护的代码变得更加简洁。
模式1 替代函数式接口
在这一模式中,我们采用原生的函数式特性来替代像Runnable
或Comparator
这样常见的函数式接口。
在这一部分中,我们引入了两个基本的函数式特性。
- 第一个特性是高阶函数(higher-order function
),它允许我们将函数作为头等数据进行传递。
- 第二个特性是匿名函数,它允许我们编写快捷的一次性函数,而无需为其指定函数名。
通过将这两个特性相结合,我们可以用一种非常简洁的方式来替代大多数的函数式接口实例。
模式2 替代承载状态的函数式接口
我们采用这种模式来替代那些需要承载某些状态信息的函数式接口实例,为此我们引入了一个新的特性: 闭包。闭包可以将某个函数和某些状态进行打包传递。
模式3 替代命令模式
替代命令模式将行为封装于某个对象之中。
在这一模式中,我们将了解如何使用在前两种模式中所介绍的技术来替代面向对象版本的命令模式。
模式4 替代生成器(Builder
)模式来获得不可变对象
通常我们采用传统的Java
约定(即一个具备getter
和setter
方法的类)来承载数据,但是这种方式却与可变性紧密相连。
在这一模式中,我们将向你展示如何从得益于不变性的Java Bean
中获取便利。
模式5 替代迭代器模式
替代迭代器模式让我们以顺序方式访问集合子项——我们将会看到如何采用高阶函数和序列推导(sequence comprehension
)来解决我们原本采用迭代器模式所解决的诸多问题,这些技术给我们带来了更具声明性的解决方案。
模式6 替代模板方法(Template Method
)模式
这一模式定义了超类中的算法轮廓,而该算法的具体细节留待子类来实现。 在这一模式中,我们将看到如何采用高阶函数和函数组合来替代这一基于继承的模式。
模式7 替代策略(Strategy
)模式
在这一模式中,我们定义了一组都实现了某一共同接口的算法。这让程序员可以简单地将一个算法实现替换成另一个算法实现。
模式8 替代空对象(Null Object
)模式
在这一模式中,我们讨论了如何去替代空对象,同时也对null
的其他处理方式进行了探讨。
在Scala
中,我们通过使用Option
利用了Scala
类型系统的优势。在Clojure
中,我们依靠了nil
和一些语言支持,从而使得对null
的处理变得更加方便。
模式9 替代装饰器(Decorator
)模式
替代的装饰器模式可以向对象添加新的行为而不改变其原有类。在这一模式中,我们将会看到如何采用函数组合来达到相同的效果。
模式10 替代访问者(Visitor
)模式
替代访问者模式使得为某种数据类型添加操作变得更简单,却难以为类型添加新的实现。本章展示了采用Scala
和Clojure
的解决方案,从而使得为数据类型添加操作和实现都成为可能。
模式11 替代依赖注入
该模式可以向某个对象注入其依赖,而非内联地实例化这些依赖,这样做将允许我们对这些依赖的实现进行替换。
我们将会探索Scala
的Cake
模式,它带给我们一种类似于依赖注入的模式。
函数式模式介绍
函数式模式
模式12 尾递归(Tail Recursion
)模式
尾递归从功能上来说与循环等效,但是它提供了一种编写递归算法的特殊方式,这种方式避免了为每次递归调用都消耗栈桢。 虽然我们在本书中更偏好声明式的解决方案,但有的时候解决问题最直接的方法就是更多地采用迭代。在本模式中,我们将会展示在这类场景中如何使用尾递归。
模式13 相互递归(Mutual Recursion
)模式
相互递归是一种递归函数互相调用的模式。和尾递归一样,我们需要为相互递归找到一种切实有效的方式来避免栈桢的消耗。
在本模式中,我们将展示如何使用一种被称为"蹦床"(trampolining
)的特性来达成这一目标。
模式14 Filter-Map-Reduce
模式
filter
、map
和reduce
是我们最常使用的三个高阶函数。通过将它们组合在一起使用,我们便获得了一个非常强大的数据处理工具。
而如今最流行的MapReduce
数据处理范式的灵感便源自它们。在本模式中,我们将看到如何在一个更小的规模中使用它们。
模式15 操作链模式
函数式编程通常会尽可能避开可变性,所以为了避免对某个数据结构进行修改,我们通常会选择一个不可变的数据结构,并对该结构进行操作,然后产生一个新的数据结构。操作链模式对在Scala和Clojure中实现这一功能的不同方式进行了考察。
模式16 函数生成器模式
高阶函数可以使用函数生成器模式来创建其他函数。 在这一部分中,我们将展示内置于多门函数式语言中的一些有关该模式的通用实例,同时对一些自定义的实例进行探讨。
模式17 记忆(Memoization
)模式
该模式通过缓存纯函数调用结果来避免对昂贵计算的重复执行。
模式18 惰性序列(Lazy Sequence
)模式
惰性序列是这样一个模式:序列中的元素仅在需要时才被逐个实例化。 这允许我们创建一个无限长的序列,从而能简单地处理数据流。
模式19 集中的可变性
集中的可变性可以通过在程序中的一小段关键性代码中使用可变数据结构来优化性能。
对该模式的需求远比你想象中的罕见。由JVM支持的Clojure
和Scala
为你提供了一套非常有效的机制来与不可变数据协同工作,所以不可变性几乎不会成为瓶颈。
模式20 自定义控制流
对于大多数语言而言,通常无法在不修改语言本身的情况下向语言添加新的控制流。 然而,函数式语言通常为创建自定义控制抽象来满足特殊用途提供了方便之门。
模式21 领域特定语言
领域特定语言模式允许我们创建一种专用语言来解决特定的问题。 使用一种经过精心设计的领域特定语言的实现,通常是处理问题的终极解决方案,因为这样做可以让我们更加贴近问题领域进行编程。 这一模式减少了我们需要编写的代码总量,同时缓解了在将想法转化成代码过程中的困扰。
Comment 1 by James Zhan 2022-12-29 13:19
不错,不错!!!