首页 > 代码库 > 9.1 改进以数据为中心的应用程序

9.1 改进以数据为中心的应用程序

9.1 改进以数据为中心的应用程序

 

我们回顾一下前面章节中讨论的以数据为中心的应用程序一些内容。第七章,我们讨论了以数据为中心的应用程序的关键是数据结构的设计。函数语言对数据结构的构造提供了非常简单、概念明确思考办法。我们已经学习了所有基本的数据类型,元组、差别联合和记录;还学习了声明泛型类型,实现了在不同程序中重用;讨论了 F# 库中的一些类型,如选项类型和函数式列表。

到目前为止,我们已经单独实现了数据类型的操作,这是函数式应用程序设计的通常方法,与面向对象程序设计不同,其中操作是类型声明的一部分。我们在第七章讨论过这一方法动机,但是,仍有必要简要回顾一下它对函数式程序的主要优势:

■ 在处理差别联合时,能够轻松地添加操作。

■在 F# 中,以这种方式写代码,语法非常简洁,因此,代码可以写得更快,而且能够很容易为不同的解决方案建立原型。

■能够充分利用 F# 的类型推理。正如我们在处理 .NET 对象时所看到的,由于编译器无法根据调用的成员推断出类型,因此,经常需要类型批注。

■这种编程风格也更好地支持了函数技术,比如散函数应用和管道。

■轻量级的函数式风格,可以使用 F# 交互式控制台(Interactive shell),轻松实现交互方式运行代码。

 

提示

 

如果操作能够保持独立于类型,数据结构就不会频繁更改。定义了数据结构以后,就可以创建这个类型的值了,并且能够一直存在于在 F# Interactive;然后,可以写函数的第一版,使用 F# Interactive 进行测试,改正可能出现的错误,对程序进行改进,并再次用同样的数据进行测试。如果我们对数据结构连同其所有的操作一起改变,这一过程将非常困难。

 

使操作成为数据结构的一部分,有许多理由支持,我们大部分经验可能来自 C#,我们用一个示例来说明。在第七章,我们写过一个简单的 Rect 类型,有两个处理函数。可以看到,清单 9.1 中重复了这段代码。示例使用了一些 System.Drawing 命名空间下的类型,因此,如果创建新项目,需要添加对 System.Drawing.dll 程序集的引用。

 

清单 9.1 Rect 类型和处理函数(F#)

open System.Drawing 

 

type Rect = 

  { Left: float32; Top: float32 

    Width: float32; Height:float32 }

 

let deflate(rc, wspace, hspace) =     <-- 缩放矩形

  { Left = rc.Left + wspace; Width =rc.Width - (2.0f * wspace) 

    Top = rc.Top + hspace;Height = rc.Height - (2.0f * hspace) }

 

let toRectangleF(rc) =     <-- 转换成 System.Drawing 表示

  RectangleF(rc.Left, rc.Top,rc.Width, rc.Height)

 

首先,我们声明了类型,然后,定义两个操作处理矩形值。操作是用独立的 F# 函数实现的,但是,如果我们把它们实现为方法,在写代码时会更容易发现。在Visual Studio 中,不需要记住函数的名字,在值的名字后键入点,智能感知会弹出操作的列表;另外,代码也更好组织,因为我们知道类型中有哪些操作。如何从这两种方案F# 中选出最好的,很明显是一个难题。

9.1 改进以数据为中心的应用程序