ビジネスルールを型システムで表現する
これにより、ルールが維持されていることをコンパイラがチェックできる
コンパイル時に自明になるので 単体テスト が不要に e.g. 顧客のメールアドレスが有効か無効かを型システムで表現する
具体的な仕様
顧客のメールアドレスには 2 種類状態が存在する
検証済み(顧客が検証メールを受け取り、確認リンクをクリックした)
未検証
これらの状態に対して、以下のようなビジネスルールがある
検証メールは、未検証のメールアドレスのみに送信する
パスワードリセットのメールは、検証済みのメールアドレスのみに送信する
フラグで表現する
code:fsharp
type CustomerEmail = {
EmailAddress: EmailAddress
IsVerified: bool
}
問題点
IsVerified がいつ何のために設定され、解除されるのかが明示されていない
検証されていないメールであっても誤って true を設定しまう可能性がある
検証済みと未検証のメールアドレスを別々のドメインとして扱う code:fsharp
type CustomerEmail =
| Unverified of EmailAddress
| Verified of VerifiedEmailAddress
このとき、VerifiedEmailAddress にプライベートコンストラクタを定義し、検証サービスだけが作成できるようにするのがポイント
type VerifiedEmailAddress = private VerifiedEmailAddress of EmailAddress
これにより、
不正な状態が表現できないように
パスワードリセットのメールは、検証済みのメールアドレスのみに送信する
code:fsharp
type SendPasswordResetEmail = VerifiedEmailAddress -> ...
e.g.「 顧客は電子メールまたは住所を持っている必要がある」というビジネスルール
このルールは顧客が以下のようなものを持っていることを暗示 メールアドレスのみ
住所のみ
メールアドレスと住所の両方
code:fsharp
type BothContactMethods = {
Email: EmailContactInfo
Address: PostalContactInfo
}
type ContactInfo =
| EmailOnly of EmailContactInfo
| AddressOnly of PostalContactInfo
| EmailAndAddr of BothContactMethods
使用例
code:fsharp
type Contact = {
Name: Name
ContactInfo: ContactInfo
}