little-hands/ddd-q-and-a

DDDを用いても「アジャイル開発のラストマイル問題」が解決していないと感じています。DDDの目的の一つは、頻繁なコード修正に耐えられるようにすること、があると思います。しかし、リリース後に①1つの集約を2つにわける、②逆に2つの集約を1つに...

Opened this issue · 0 comments

Question

DDDを用いても「アジャイル開発のラストマイル問題」が解決していないと感じています。

DDDの目的の一つは、頻繁なコード修正に耐えられるようにすること、があると思います。しかし、リリース後に①1つの集約を2つにわける、②逆に2つの集約を1つに統合する、といった大きなモデル変更が入ると、集約の単位が変わるためテーブル構成も変わり、結果としてデータ移行が必須になりませんか?(フィールド追加で済むような簡単なモデル変更は想定していません)

データ移行が発生するとなると、本番リリース後はそんな簡単にモデルを変更できないのではないでしょうか。結果として、小手先の対応をすることでモデルとコードが乖離してしまう気がします。

大きなモデル変更をする場合、痛みに耐えてデータ移行するしかないのでしょうか。それとも、うまい設計方法があるのでしょうか。

Answer

DDDだったらデータ移行が不要になるということは全くありません。
モデルを変更したら、長期的に価値があるのであれば、コストを払って実装も追従するかを検討します。ここで、オニオンアーキテクチャなどで、DBへの依存を外側のレイヤーで押し込めることで、「コードは変更するがDBが追従するタイミングを遅らせる」という選択肢が取れるようになります。
オニオンアーキテクチャでは、ドメイン層のオブジェクトをDBにマッピングするのはインフラ層にあるリポジトリの実装クラスです。このクラスがクッションの役割と果たしてくれるようになるおかげで、ドメインオブジェクトの形は変えてもDBは後にする、もしくはDBから先に変更してしまう、と言った柔軟な移行戦略が取れるようになります。ActiveRecord型のORMを直接使っていると、オブジェクトとDBの結合が強いので同時に切り替える制約が強まります。
集約の変更に関しては、オブジェクトも大きくリファクタするためにたしかにコストがかかりますが、それでもDBの作りはそのままでオブジェクトの変更だけでまずは進めるなど、柔軟に方法を考えられます。
もちろん、そのリファクタに価値があるかは、そのコードをその後どれくらい修正するか、どれくらい重要な機能か、と言った観点からリファクタ口数がペイするかを検証する必要があります。