需要有关使用F#遵守开放/关闭原则的指导

时间:2015-11-13 15:35:07

标签: f#

在F#中编程时,有哪些模式可用于遵循开/关原则?

例如,我确信F#中的模式匹配在某些情况下很棒。 但是,每当新业务案例进行操作时,如果您不想修改模式匹配构造,那么存在哪些指导?

示例:

let getFullName nickName = 
    match nickName with
    | "Bizmonger" | "Rico" -> "Scott Nimrod"
    | _ -> "not found"

getFullName "Bizmonger";;

引入新病例会发生什么?

因此,我不想继续修改这个功能。

2 个答案:

答案 0 :(得分:5)

我认为你遇到的问题的关键是表达问题。

使用代数数据类型的功能代码位于一侧,用于定义初始问题域以及创建和添加在该域上运行的新功能。另一方面,这是相当困难的,特别是一旦你开发了一系列函数来向初始域添加类型。

面向对象的代码位于问题的另一端。一旦定义了初始问题域,添加新功能就变得非常困难,因为必须扩展所有类型才能实现它,但将域扩展到新问题相对容易。

考虑

npm install -g jasmine-core

在这里,添加函数很容易,因为我可以为每种类型的形状定义行为,但是很难添加新的形状,因为我必须编辑每个函数。

type Shape =
    |Circle of float
    |Square of float * float

module Shapes =
    let area = function
        |Circle r -> Math.PI * r ** 2.0
        |Square (a, b) -> a*b

    let perimeter = function
        |Circle r -> 2.0 * Math.PI * r
        |Square (a, b) -> 2.0 * (a + b)

使用OO,添加新形状很容易,但是要对Shape进行新的属性或方法很难,因为我必须编辑每种类型。

我不知道你是否曾在面向对象编程中使用过访问模式,但是对该模式的需求源于表达结构的难度,这些结构可以通过函数式编程中的代数数据类型轻松表达。

作为通用编程语言的F#的一大优点是,您可以根据问题确定在问题上使用哪种表达特定问题的方法。这为您提供了极大的灵活性,可以为您的软件设计选择最佳方法。

答案 1 :(得分:4)

正如你在这种情况下发现的那样,很容易添加新功能(你可以说它在这方面是公开的)但很难添加新的情况

但是当然你可以像在C#中一样使用F#中的类/对象/接口,因此你也可以获得众所周知的OOP模式

btw:无论如何String不是实施商业案例的好选择......你不会得到OOP O / C而且你不会这样得到FP联盟类型的好东西