在F#中编程时,有哪些模式可用于遵循开/关原则?
例如,我确信F#中的模式匹配在某些情况下很棒。 但是,每当新业务案例进行操作时,如果您不想修改模式匹配构造,那么存在哪些指导?
示例:
let getFullName nickName =
match nickName with
| "Bizmonger" | "Rico" -> "Scott Nimrod"
| _ -> "not found"
getFullName "Bizmonger";;
引入新病例会发生什么?
因此,我不想继续修改这个功能。
答案 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联盟类型的好东西