在F#编程时,有哪些模式可用于遵循开/关原则?
例如,我确信F#中的模式匹配在某些情况下很棒.但是,如果您不想在每次操作新业务案例时修改模式匹配构造,那么存在哪些指导?
例:
let getFullName nickName =
match nickName with
| "Bizmonger" | "Rico" -> "Scott Nimrod"
| _ -> "not found"
getFullName "Bizmonger";;
Run Code Online (Sandbox Code Playgroud)
引入新病例会发生什么?
因此,我不想继续修改这个功能.
我认为你遇到的问题的关键是表达问题.
使用代数数据类型的功能代码位于一侧,用于定义初始问题域以及创建和添加在该域上运行的新功能.另一方面,这是相当困难的,特别是一旦您开发了一组函数来向初始域添加类型.
面向对象的代码位于问题的另一端.一旦定义了初始问题域,添加新功能就变得非常困难,因为必须扩展所有类型才能实现它,但是将域扩展到新问题相对容易.
考虑
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)
Run Code Online (Sandbox Code Playgroud)
在这里,添加函数很容易,因为我可以为每种类型的形状定义行为,但是很难添加新形状,因为我必须编辑每个函数.
[<AbstractClass>]
type Shape() =
abstract member Area : double
abstract member Perimeter : double
type Circle(r) =
inherit Shape()
override this.Area = Math.PI * r **2.0
override this.Perimeter = 2.0 * Math.PI * r
type Square(a, b) =
inherit Shape()
override this.Area = a*b
override this.Perimeter = 2.0 * (a+b)
Run Code Online (Sandbox Code Playgroud)
使用OO,可以很容易地添加新形状,但是要对Shape进行新属性或方法很难,因为我必须编辑每种类型.
我不知道你是否曾经在面向对象编程中使用过访问模式,但是对该模式的需求源于表达结构的难度,这些结构可以通过函数式编程中的代数数据类型来表达.
F#作为通用编程语言的一大优点是,您可以根据问题确定在问题上使用哪种表达特定问题的方法.这为您提供了极大的灵活性,可以为您的软件设计选择最佳方法.