我正在使用F#为其中一个应用程序编写域逻辑。我想控制对F#中为类型定义的字段的访问,以便可以实现构建器模式和控制类型实例化。
想与C#/ Java中的构建器模式做类似的事情。
请提出建议。
例如 让Person = { 名称:字符串 年龄:人数 工资:字符串 }
因此,我想确保应该始终使用Name和Age实例化该人。但是薪水应该是可选的。实例化应该以构建器模式进行。
答案 0 :(得分:2)
您不能创建单个记录字段private
或internal
,但是可以创建所有字段private
或internal
。这将隐藏所有字段,因此您必须公开要使其成为成员可访问的那些字段。您还可以添加静态方法来创建新值。例如:
type Person =
private {
name : string
age : int
salary : int option }
member x.Name = x.name
member x.Age = x.age
member x.Salary = x.salary
static member Create(name:string, age:int) =
{ name = name; age = age; salary = None }
member x.WithSalary(s) =
{ x with salary = Some s }
现在您无法访问字段或直接创建记录,但是可以使用Create
和WithSalary
:
Person.Create("Joe", 60).WithSalary(10000)
答案 1 :(得分:1)
正如评论中指出的那样,似乎您正在尝试使用没有对象的面向对象模式,这不是一个好主意。
如果您决定使用F#类型,则可以这样做:
type Employee = {
name: string
age: int
salary: int option
}
let person1 = {
name = "Mike",
age = 42,
salary = Some 4200
}
let person2 = {
name = "Sue",
age = 37,
salary = None
}
省略名称或年龄会给您带来编译时错误,就像使用person1或person2一样,而无需检查工资是否存在。
要使用私有数据实施类似于构建器模式的操作,请执行以下操作:
type Employee = private {
name: string
age: int
salary: int option
}
let name employee = employee.name
let employee name age = { name = name; age = age; salary = None }
let withSalary salary employee = { employee with salary = Some salary }
let mike = employee "Mike" 42 |> withSalary 4200
mike.name //return name of this employee
答案 2 :(得分:1)
您可以使用简单的函数来实现构建器模式。我没有理由在这里使用对象:
type person =
private {
name: string
age: int
salary: int option
}
let name person = person.name
let age person = person.age
let salary person = person.salary
let create name age =
{ name = name; age = age; salary = None }
let withSalary salary person =
{ person with salary = Some salary }
create "Joe" 60
|> withSalary 10000
|> name