Entityに対してinsideでIdentifierを定義する
Entity(だが、まだidを持っていない)Objectに対して、どのようにIdentifierを定義するか insideとoutsideの2つのアプローチがある
結論としては、前者のほうが良い
具体例を見るために、軽く状況設定をしておく
『Domain Modeling Made Functional』.iconの内容と同じ
いま、請求書(Invoice)のEntityを定義しようとしている
Invoiceには支払い済みかどうかのデータをもたせたい
これを、Paid | Unpaidで表現する
InvoiceはEntityなのでIdentifierを付与したい
outsideで定義した場合
not associated wih to any of the cases
コード例
2つの言語で書いているが同じmrsekut.icon
code:purs(hs)
data Invoice = Invoice {
id :: InvoiceId,
info :: InvoiceInfo
}
data InvoiceId = String
data InvoiceInfo = Unpaid UnpaidInvoiceInfo
| Paid PaidInvoiceInfo
type UnpaidInvoiceInfo = ...
type PaidInvoiceInfo = ...
code:ts
type Invoice = {
id: InvoiceId
info: InvoiceInfo
}
type InvoiceId = string
type InvoiceInfo = UnpaidInvoiceInfo | PaidInvoiceInfo
type UnpaidInvoiceInfo = ...
type PaidInvoiceInfo = ..
Invoiceに対してidをもたせており、その中でinfoがUnionになっている
言いたいことをわかりやすく書くと、
code:ts
type Invoice = {
id: InvoiceId
info: UnpaidInvoiceInfo | PaidInvoiceInfo
}
これの問題点は、Invoiceを一つの状況で使用したい際にやや複雑になってしまう
データが異なるcomponentに分散しているため、1つの状況のデータを簡単に処理することが難しい
例えば、Invoiceの特にPaidな状態のものを扱いたい際に、Invoiceそのものを持ち回って内部で条件分岐する必要がある
つまりPaidInvoiceInfoのみで作業ができない
こいつにはidが含まれていないのでmrsekut.icon
insideで定義した場合
associated with each case
コード例
2つの言語で書いているがほぼ同じmrsekut.icon
code:purs(hs)
data Invoice = Unpaid UnpaidInvoice
| Paid PaidInvoice
data InvoiceId
data UnpaidInvoice = UnpaidInvoice {
id :: InvoiceId
info :: ..
}
data PaidInvoice = PaidInvoice {
id :: InvoiceId
info :: ..
}
code:ts
type Invoice = UnpaidInvoice | PaidInvoice
type InvoiceId = string
type UnpaidInvoice = {
type: 'unpaid'
id: InvoiceId
info: ..
}
type PaidInvoice = {
type: 'paid'
id: InvoiceId
info: ..
}
状況ごとにEntityを定義して、その直積としてInvoiceを定義する
同じ意味を持つ(Invoice Entityの)idがいくつかの場所で定義されることになる
状況ごとに全てのfieldにアクセスできる
code:purs(hs)
f :: Invoice -> String
f = case _ of
Unpaid u -> show u.id <> show u.info
Paid p -> show p.id <> shwo p.info
参考