【问题标题】:static members vs module for type in F#?F# 中类型的静态成员与模块?
【发布时间】:2018-12-30 16:39:29
【问题描述】:

假设我有这样的类型:

type Season =
| Spring
| Summer
| Autumn
| Winter

我想要一个返回下一季的函数next

let next s = 
  match s with
  | Spring -> Summer
  | Summer -> Autumn
  | Autumn -> Winter
  | Winter -> Spring

我可以在两个地方放置这个函数。

在命名模块中:

module Season = 
  let next s = 
    match s with
    | Spring -> Summer
    | Summer -> Autumn
    | Autumn -> Winter
    | Winter -> Spring

或者作为类型上的静态成员:

type Season =
| Spring
| Summer
| Autumn
| Winter
  with 
    static member next s = 
      match s with
      | Spring -> Summer
      | Summer -> Autumn
      | Autumn -> Winter
      | Winter -> Spring

支持每种方法的原因是什么?

【问题讨论】:

  • 枚举可能更适合这种特定情况。如果你需要上一季怎么办?模块实际上只是 F# 中的名称间距结构,它适用于库函数(例如自动打开的 List),否则我会避免使用它。也就是说,它可以很好地用于域建模,并且您可能在 Season 上运行很多函数,其他语言通过能够在类型之外的类型上定义方法来解决它,但是模块可能适合您。太糟糕了,你不能接受两个答案。 :D

标签: f#


【解决方案1】:

最终,这是一个领域建模判断调用,这里没有一个明确的正确答案。重要的是每个选择如何影响代码的可读性和可维护性。

我倾向于使用与类型高度“内聚”的功能的静态成员,而不是任何特定的业务逻辑代码。想想Parse 函数或智能构造函数/工厂方法。一般的方法是,如果我通过将类型移动到其他地方来重构代码,那么我肯定希望将这些函数与它一起移动。将它们作为静态成员还有助于通过智能感知进行发现,因为您只需要知道类型的名称即可找到它们。

另一方面,我会使用一个模块来容纳代表一些抽象流程的业务逻辑,如果所讨论的功能在某种程度上特定于该业务逻辑并且不太可能在它之外有用,那么我会使用模块中的函数,即使它仍然有点特定于类型。例如,一个非常特定于目的的解析器,由于遗留原因仅作为这个工作流的一部分有用,它将是一个 let-bound 函数而不是一个静态成员,因为使用该类型的其他客户端通常甚至不应该知道该函数.

在你的情况下,我会选择静态成员 Next,如果它在你的上下文中用于多个不同的模块是有意义的 - 如果能够循环通过 Seasons 是定义的基本质量Season 是什么。

否则,如果您只有一个模块,比如说WeatherPatterns,它会根据季节变化调整降雨量,这是您代码中唯一关心循环通过Seasons 的部分,那么我会说作为该模块中的一个函数。

【讨论】:

    【解决方案2】:

    您的示例非常简单,因此这里的任何一种方法都可能很好。但想象一下添加十几个采用 Season 参数的函数。现在类型定义看起来会非常混乱。此外,这些函数可能需要使用一些可以在 Season 模块中声明为私有的共享值和函数。

    【讨论】:

      【解决方案3】:
      • 可以重载非柯里化静态成员方法。模块函数不能。
      • C# 仅将模块视为 [name_of_module]Module,例如SeasonModule.
      • 通过open模块可以在不指定模块的情况下访问模块值和函数(例如next而不是Season.next)。 (当然,这可以通过 RequireQualifiedAccess 属性来禁止。)

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2011-01-24
        • 1970-01-01
        • 1970-01-01
        • 2012-04-13
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多