はじめに
こんにちは、ソフトウェアエンジニアの くる です。
ビジネスロジック以外もモデリングに落とし込む話。
主にweb開発のcontextで話します。
ドメイン駆動設計という手法のなかで、自分の認識だと割と永続化レイヤーを抽象化し、モデリング側にはあまりその事情を持ち込むべきではない。という論があるのかなと思います。
これ自体は自分も大方針としてはagreeなのですが、そこに囚われすぎると不自由もあるという話。
モデリング
たとえば、商品の在庫管理のアプリケーションで
ItemStock みたいな商品の在庫数を表現するモデリングを実装する必要があるとします。
これに対して、何かしらの都合でデータソースが分かれているときに、その都合を反映したような実装レベルのモデリングをするのは、あまり筋が良くないとは感じます。
ItemStockFromMysqlItemStockFromRedis
みたいな。ドメインとして同じ情報なら同じモデリングには収めたいですね。
一方でweb開発において実装やロジックから永続化レイヤーの都合を完全に分離できるかというと、なかなかそれは難しいです。
上記の状況でいうと、
- mysqlであることはとらわれなくてもよいが、masterとしているdbから取った一次情報である
- redisということはとらわれなくてもよいが、キャッシュされた情報である
このような都合が実際はあるのかなと思います。
こういうときもモデリングしましょうというのが、この記事の本題でした。
具体どうするかというと、この例で言えば下記のようなモデリングにします
ItemStockCached<ItemStock>
基本的な在庫の処理を行うときは ItemStock のモデリングを使う。一方で、ユーザー表示だけのusecaseで、アクセスの多い場面ではキャッシュされたデータの方が非機能要件に合うためキャッシュされたデータを表現する Cached<ItemStock> を扱う。といった感じです。
キャッシュ先のデータソースの具体は知る必要がないにしても、キャッシュされた情報である。という事実はビジネスロジックとみなすべきかな。という感じです。
これがdbのレイヤーが入り込んできて嫌と言われるとなかなか難しいものの、アプリケーションにおけるドメインロジック(ビジネスロジック / 非機能要件由来のロジック)の境界をどこに置くか、という感じです。
結局リーディングするときの認知負荷を下げることを考えたときに、dbなど非機能要件のstateもモデリングに組み込むことが必須かなというのが主張でした。
他の場面
また、例えば上記のような在庫処理では、実際に在庫を増減させる時にはロックをとり排他処理を行いたい場面が出てくると思います。そういう時のstateもオンメモリで状態を表すために、例えば
Locked<ItemStock>
のようなモデリングを行うことで、データに付随する状態も表現したまま実装上扱うことができるようになるかな。と思います。
ジェネリクスのない言語ではモデリングの数がかなり増えて辛い部分もあるかもしれないですが、考え方としては変わらないかなと。
さいごに
結局の主張としてはビジネスロジック、なんてワードは少し曖昧なところもあるので、ビジネスロジックだけをモデリング対象とせず、モデリングでもっと表現していこうというのがこの記事の主張でした。