この投稿に続いて https://stackoverflow.com/questions/21554977/should-services-always-return-dtos-or-can-they-also-return-domain-models とソフトウェアのベストプラクティスマーティン・ファウラーによるアーチの提案
サービスレイヤーは、アプリケーションの境界[Cockburn PloP]と、クライアントレイヤーとのインターフェースの観点から使用可能な一連の操作を定義します。アプリケーションのビジネスロジックをカプセル化します
私はそうすることに問題があります、以下を考慮してください:
UserService {
UserDto findUser();
}
UserServiceは、データのみが必要なコントローラーで使用する場合は問題ないため、dtoで十分です。
しかし、このサービスを別のサービスで使用した場合の問題は次のとおりです。例:CustomerService
モデル自体はUser
オブジェクトが必要なので、モデルは永続コンテキストで管理する必要があります
例えば
CustomerService {
void addCustomer() {
Customer customer = new Customer();
User user = userService.fimndUser(xxx); // BAM compilation fails since findUser returns UserDto not User
customer.setUser(user);
}
}
ここでは、2つの異なる戻り値型のfindUser
メソッドの2つのコピー、またはUserService
クラスの2つのコピー(コントローラー用とサービスまたはコアパッケージ用の2つ)、またはプロキシパターンを実装する
非常に単純な経験則では、データを転送する必要がある場合にのみDTOオブジェクトを使用する必要があります。つまり、Web APIの境界で、またはメッセージバスでオブジェクトを送信するときにDTOを使用します。内部的には、ドメインオブジェクトを使用するだけです。
DTOが存在する必要がある唯一の理由は、(逆)シリアル化レイヤーの制限です。これらには、複雑なロジックのない単純なオブジェクトが必要です。
勧告:
これにより、必要に応じてサービスを使用し、実際に必要なときにDTOを保存できます。