8.3.2 构建组合行为

来源:互联网 发布:安达信软件怎么装 编辑:程序博客网 时间:2024/05/17 23:09

8.3.2 构建组合行为

 

    在清单 8.11 中,验证最低收入和当前工作最小年份的检查和报表函数中,有明显的重复。这些检查有类似的结构:都检查客户的某一属性是否小于最小的允许值。

    找出共性是只删除重复第一步。下一步是要看 checkJobYears 和 checkIncome 函数(连同其报表函数)的哪部分是不同的:

    ■ 检查不同的属性。

    ■ 使用不同的最小值。

    ■ 有略微不同的消息。

    要更简洁地写出代码,我们可以创建一个函数,取这三个不同的部件作为其参数值,并返回 ClientTest 记录。当我们创建检查列表时,用不同的参数值调用这个新函数两次,创建两个类似的检查。清单 8.13 显示额外的函数(lessThanTest),以及创建检查列表的新方法。

 

Listing 8.13 Creating similar tests using a single function (F# Interactive)

 

> let lessThanTest readFunc minValue propertyName =
     let report client =
       printfn "Checking '%s' of '%s' failed (less than %d)!"
                   propertyName client.Name minValue
     { Check = (fun client -> readFunc(client) < minValue)
      Report = report };;
val lessThanTest : (Client -> int) -> int -> string –> ClientTest

> let tests =
     [ (lessThanTest (fun client -> client.Income) 30000 "income")
       (lessThanTest (fun client -> client.YearsInJob)
                             2 "years in the job")
(* more tests... *) ];;
val tests : ClientTest list

 

    像往常一样,这个类型签名告诉我们很多关于这个函数的信息。LessThanTest 函数返回值为 ClientTest,包含了检查和报表函数。检查是用三个参数值生成的:

    1 读客端的一个数字属性

    2 指定必需的最小值 (在本例中,表示收入或年数)

    3 描述属性 (用于报表检查)

    这段代码首先声明一个嵌套函数 report,取客户作为参数值,打印检查未通过的原因。这个函数还使用 lessThanTest 函数的参数值,这意味着,当 report 作为结果的一部分返回时,所有这些参数将捕获在一个闭包中。当构建一个将返回的记录值时,我们指定 report 作为这个函数值的一部分,第二部分写成内嵌的,使用 lambda 函数。

    使用函数的元组或记录,在函数式编程中很常见,它反映了 F# 的开发风格。但在 C# 中,我们将使用不同的方法来实现这个示例。让我们看一下,在开发过程中,还要考虑如何在 C# 中实现这个示例,并改善当前的 F# 版本。

原创粉丝点击