第十一章 重构和测试函数式程序

第十一章重构和测试函数式程序

本章介绍

■重构函数式程序

■使用不变性推理代码

■为 F# 程序写单元测试

■使用延迟值缓存结果

这本书的主题之一就是,函数编程理如何使解代码更容易理解,只需要通过阅读就可以;特别是在需要修改陌生程序,或者通过组合现有函数实现行为,或者重构现有的代码时,尤为重要。函数式编程更容易重构,缘于清晰度和模块化:可以改善代码,并且有信心这种改变不会破坏程序的其他部分。

正如在函数式编中的很多事情一样,修改代码而不改变其含义的思想,与数学密切相关,因为不改变表达式含义的操作是许多数学任务的基础。我们可以把一个复杂的等式,化简(simplify)得到更易于阅读、但意思相同的等式。我们看看下面的方程:y = 2x + 3(5 - x)。如果我们用3 乘以括号中的表达,可以写成y = 2x + 15 - 3x,又可以简化为:y = 15 – x。

来自数学的另一种技巧是替换(substitution)。如果有两个方程,y = x/2 和x = 2z,我们可以把第二个方程的右边代入第一个方程,就得到(化简后)y = z。最重要的一点是,把一个正确的方程替换成另一个方程,得到的方程不会突然变得不正确。这种方法在函数编程称为组合(composition)。

函数编程与是数学密切相关,所以,代数中的一些应用到函数式程序中,毫不奇怪。在编程的世界里,化简方程对应于重构(refactoring),这是本章的核心。特别是,我们将讨论减少重复代码和代码的依赖关系。

替换也是一种形式的重构,但是,我们将知道,它还有其他的重要优势,尤其是在单元测试当中。替换能够把精力集中在测试基本函数,花更少的时间测试,由简单的预制块组合的函数,因为组合不会破坏已测试的组件。

我们还将研究与重构密切相关的主题。如果程序没有副作用,其中个别部分不管搂什么顺序执行,应该得到同样的结果。值,只要声明,就可以计算,也可以延迟执行,直到真正需要这个值时。这种技术称为延迟laziness(或延迟计算lazy evaluation),当我们探讨潜在的无穷数据结构和计算机值的缓存时,将展示一些实际的好处。

时间: 2024-10-05 04:27:36

第十一章 重构和测试函数式程序的相关文章

《Python核心编程》第十一章:函数和函数式编程

本章大纲 介绍函数的创建.调用方式,内部函数.函数装饰器.函数参数的定义和传递.函数式编程.变量作用域.闭包. 知识点 11.1 什么是函数? 函数是对程序逻辑进行结构化或过程化的一种编程方法,以实现代码的复用. python 的过程就是函数,因为解释器会隐式地返回默认值 None. python 动态地确定函数返回类型,而不是进行直接的类型关联. 可以使用 type() 函数作为代理,处理有不同参数类型的函数的多重声明,以模拟其他编程语言的函数重载. 11.2 调用函数 11.2.1 关键字参

第十一章 分布式应用程序

第十一章分布式应用程序 使用网络的应用程序,称为分布式应用程序(distributed applications),现在,已经越来越重要.幸运的是,.NETBCL 和其他的库提供了许多结构,使得通过网络通信变得容易,进而,用 F# 创建分布式应用程序也是很简单. 网络概述 已有几类分布式应用程序,通常分为:客户端-服务器(client-server)应用程序,其中客户端向中央服务器的请求:点对点应(peer-to-peer)用程序,萨满教这里,计算机之间相互交换数据.这一章,我们将重点学习客户端

Python 编程快速上手 让繁琐工作自动化-第十一章实践项目 11.11.1命令行邮件程序

11.11.1 命令行邮件程序 编写一个程序,通过命令行接受电子邮件地址和文本字符串.然后利用selenium登录到你的邮件账号,将该字符串作为邮件,发送到提供的地址(你也许希望为这个程序建立一个独立的邮件账号).这是为程序添加通知功能的一种好方法.你也可以编写类似的程序,从Facebook 或Twitter 账号发送消息.这个项目弄了好几天,头都快炸了,终于弄好了代码如下:#!/usr/bin/env python#encoding:utf-8 '''@author:Kevinbr/>@aut

1.4.2.1 阅读函数式程序

我们在清单 1.1 中看过一个示例,就是使用了不可变类型,我们的结论是,不可变类型使代码更具可读性.在本节,我们将考虑两段代码,可以用在我们函数式游戏中. 清单 1.8 中有两个示例,都涉及两个游戏角色(player 和 monster).第一个示例说明怪物[1] [ 原文中的 AI,应该就是这个 1 ]如何移动一步,然后,判断玩家是否正处于危险之中,第二示例演示如何射击. Listing 1.8 Code snippets form a functionalgame (C#) var move

软件工程第一章至十一章汇总

第一章软件软件是计算机程序,规程及运行计算机系统可能需要的文档和数据.软件分为通用软件和定制软件.软件的特性:1.复杂性2.不可见性3.不断变化4.大多数软件仍然是定制的,而不是通过已有的构件组装而成.软件于二十世纪50~60年代,70年代,80年代,90年代至今进行发展.在此过程中遇到一些危机:1.软件的开发成本和进度难以估计,延迟交付甚至取消项目的现象屡见不鲜.2.软件存在着错误多,性能低,不可靠,不安全等质量问题.3.软件的成本在计算机系统的整个成本中所占的比例越来越大.4.软件的维护极其

软件工程——理论方法与实践(段落概述第一章至第十一章)

第一章软件软件是计算机程序,规程及运行计算机系统可能需要的文档和数据.软件分为通用软件和定制软件.软件的特性:1.复杂性2.不可见性3.不断变化4.大多数软件仍然是定制的,而不是通过已有的构件组装而成.软件于二十世纪50~60年代,70年代,80年代,90年代至今进行发展.在此过程中遇到一些危机:1.软件的开发成本和进度难以估计,延迟交付甚至取消项目的现象屡见不鲜.2.软件存在着错误多,性能低,不可靠,不安全等质量问题.3.软件的成本在计算机系统的整个成本中所占的比例越来越大.4.软件的维护极其

[原创译书] JS函数式编程 2.3 函数式程序员的工具集

?? Functional Programming in Javascript 主目录第二章 函数式编程基础上一节 与函数共舞 函数式程序员的工具集 如果你仔细看了到目前为止出现过的示例代码,你会发现这里面的一些方法不太熟悉. 它们是map().filter()和reduce()函数,它们对任何语言的函数式编程都至关重要. 它们可以让你不必使用循环和语句,写出更简洁的代码. map().filter()和reduce()函数组成了函数式程序员工具集的核心部分,这个工具集包括一系列纯的. 高阶的函

《Java并发编程实战》第十一章 性能与可伸缩性 读书笔记

造成开销的操作包括: 1. 线程之间的协调(例如:锁.触发信号以及内存同步等) 2. 增加的上下文切换 3. 线程的创建和销毁 4. 线程的调度 一.对性能的思考 1 性能与可伸缩性 运行速度涉及以下两个指标: 某个指定的任务单元需要"多快"才能处理完成.计算资源一定的情况下,能完成"多少"工作. 可伸缩性: 当增加计算资源时(例如:CPU.内存.存储容器或I/O带宽),程序的吞吐量或者处理能力能相应地增加. 2 评估各种性能权衡因素 避免不成熟的优化.首先使程序正

perl5 第十一章 文件系统

第十一章  文件系统 by flamephoenix 一.文件输入/输出函数  1.基本I/O函数    1)open函数    2)用open重定向输入    3)文件重定向    4)指定读写权限    5)close函数    6)print, printf和write函数    7)select函数    8)eof函数    9)间接文件变量  2.跳过和重读数据  3.系统读写函数  4.用getc读取字符  5.用binmode读取二进制文件二.目录处理函数  1.mkdir  2