はじめに
本記事は以下の書籍を読んで学んだことをまとめることを目的としています。
前回の続きです。
ドメイン駆動設計入門 ボトムアップでわかる! ドメイン駆動設計の基本 | 成瀬 允宣 |本 | 通販 | Amazon
リポジトリ
ドメインオブジェクトの永続化や再構築を行います。オブジェクトのインスタンスを保存・復元するときは、直接DBに対して操作を行うのではなく、リポジトリのインターフェースに依頼します。
リポジトリを使用する理由
- ドメインオブジェクトがドメインを表現することに集中するため
- ソフトウェアに柔軟性を持たせるため
- テストを容易にするため
リポジトリは実現したいアプリケーションの概念に出てくるものではないですが、もしこれが無ければ、前回までで紹介した、ドメインオブジェクトやドメインサービスに、データの保存や復元のためのとあるDBの詳細で複雑な実装をが出てくることになります。ドメインに本質的に関係のない実装が増えることで、そのドメインの持つの意味や振る舞いが薄れ、DB操作の実装により、何をしているメソッドなのか理解するのに時間がかかり、可読性が落ちます。
また、インターフェースにすることにより、特定のDBや技術に依存せず開発がで、柔軟性が高まるというメリットがあります。さらに、インターフェースであることにより、モック化など置き換えが可能なため、テストがしやすいというメリットもあります。
アプリケーションサービス
アプリケーションサービスとはドメインオブジェクトを使用して、ユースケースを実現するためのオブジェクトです。
実装上の工夫
DTOを使う
ドメインオブジェクトを操作し、その結果オブジェクトをそのままクライアント側に返してしまうと、アプリケーションサービス以外からドメインオブジェクトのメソッド呼び出すという意図しない実装が起きる可能性が出てきます。
また、本来アプリケーションサービス1箇所に記述されるべきロジックが様々な箇所に散ってしまうので、DRY原則に反する可能性もあります。
そのため、筆者はDTO(Data Transfer Object)にデータを移し替えて、外部には必要なデータのみを公開するという方法をおすすめしていました。
コマンドオブジェクトを使う
例えば、ユーザー情報を更新するというユースケースを考えます。最初はユーザー名しかユーザー情報がなかったため、ユーザー情報を更新するメソッドの引数はユーザー名のみでした。しかし、ほかにも住所やメールアドレスなどさまざまなユーザー情報が増えていくとすると、そのたびにメソッドの引数を増やすこととなり、シグネチャが変わります。
そのため、ユーザー情報を更新するメソッドは、直接更新したいユーザー情報を引数で受け取るのではなく、更新したいユーザー情報を持つコマンドオブジェクトを作成し、それを引数で受け取るようにすることで、メソッドのシグネチャが変更されないようにするという方法が紹介されていました。
実装上の注意
ドメインロジックを書かないこと
例えばユーザー登録・更新の重複チェックはドメインサービスに任せるようにします。前回まででも言っているように、ドメインのルールはドメインオブジェクトに閉じ込めること同じようなロジックの点在を防ぐことができます。
凝集度を高めること
全てのメソッドが、全てのフィールドを使っている状態は「凝集度が高く」、コードの見通しが良くなります。一部のフィールドしか使っていないメソッドは、別クラスに切り出せる可能性があります。ただし、凝集度が絶対の指標ではなく、あくまでもコードを整理するための一つの指標であることを覚えておきましょう。
インスタンスの状態によってふるまいを変えない
状態を一切持ってはいけないという意味ではなく、インスタンスの状態によってふるまいを変えないようにします。
状態によって振る舞いがかわると、実装者がサービスを使うときに、状態を気にしなければならず、複雑度が増してしまいます。
さいごに
ここまでお読みいただき、ありがとうございました。
長くなるので、#4に続きます。