如何实现一个策略模式来返回一个声明为private的结构?
或翻译......
如何将私有结构的创建限制为多个函数?
我想为用户登录操作实现IOlogin解释器和MockLogin解释器.这两个函数应返回AuthenticatedManager类型的值.
从入门开始,我想在这样的模块中定义一个类型:
module Specification =
type AuthenticatedManager = private { Name:string }
Run Code Online (Sandbox Code Playgroud)
上面的代码旨在限制AuthenticatedManager的创建.
我想在一个单独的模块中引用AuthenticatedManager:
module Mock =
open Specification
let username = Username "test_manager"
let password = Password "123"
let invalidPassword = Password "invalid password"
let login username' password' : Result<AuthenticatedManager,Username*string> =
if ( username',password') = ( username,password )
then Ok { Name="authenticated manager" } // compile error
else Error ( username',"Failed to login" )
Run Code Online (Sandbox Code Playgroud)
我知道编译错误源于我试图引用我声明它的模块之外的私有结构.但是,我认为有一些单独的库来容纳这类操作的解释器是有意义的.
您应该为每个类型定义一个带有私有构造函数的模块,并为该模块中的类型提供create和value函数.模块应该与类型在同一个编译单元中,因此它可以访问私有构造函数.以下是我一直使用的模式的简单示例:
[<Struct>] type Username = private Username of string
// Make one module for each type
module Username =
let create = function // Use whatever the real business rules are here
| username when not <| String.IsNullOrEmpty(username) -> Ok <| Username username
| _ -> Error "Username must not be blank"
let value (Username username) = username
Run Code Online (Sandbox Code Playgroud)
然后,在您需要的任何地方Username,您可以调用create有权访问私有构造函数的函数,并验证数据并为您构建数据.同样的,你需要的地方提取原料string从Username,您使用的value功能.