web-dev-qa-db-ja.com

DTOを備えたサービス層

サービスレイヤーを使用するように設計をリファクタリングしていますが、エンティティの特定のフィールドの更新のみが許可されている場合、引数を渡す方法について混乱しています。たとえば、作成時にのみ設定できるいくつかのフィールドがあります(メタデータ)。しかし、サービスレイヤーについて私が目にするすべての例では、エンティティを引数として使用しています。 update(Entity entity)。すべての値が変更されている可能性があります。注文を追加できるようにしたいだけの場合(顧客のその他の部分は変更しないでください)。これは次の方法で実行できます。

customer.add(new Order())
service.update(customer)

とても素敵に見えますが、サービスに気づかれることなく、顧客の他のフィールドを変更することができました。私の代替案は次のようなものです:

service.addOrder(customer, new Order())

これは妥当なようです。ただし、これにより、非常に長いパラメーターリスト(不良)を持つメソッドが作成され、同じエンティティが(サービスレイヤーと以前に使用されていた場所の両方で)2回ロードされる可能性があります。エンティティの部分的な更新ごとにDTOとメソッドを作成するほうがよいでしょうか?これには、データベースから(場合によっては)既に読み込まれているエンティティを読み込むために、サービス層またはリポジトリのいずれかが必要になります。

1
Anders

これらの両方を機能的に同じようにすることもできますが、同じことを示唆するものではありません。

1つ目は、注文の追加はお客様に行うことです。 OrderオブジェクトをCustomerオブジェクトに渡し、何かを実行することを期待しています。それは単に参照を作成することかもしれませんし、それに伴う大量のビジネスロジックがあるかもしれません。どちらの方法でも、Customerオブジェクトは注文オブジェクトの処理方法を認識しています。次に、データを保存するサービスに顧客を渡します。そのサービスが行うすべては顧客を取り、それを節約します。注文の追加を気にすることはできませんでした。

2番目は非常に異なる何かを示唆しています。 2つ目は、サービスがすべてのビジネスロジックの行き先であると想定しています。これは、お互いについて何も知らない2つのオブジェクトが渡され、それらのオブジェクトで何をすべきかを知っていることが期待されているためです。

どちらが正しいかはあなたの状況に依存しますが、私の推測が最初です。 2つ目は、2つのオブジェクトの相互作用をサービスに依存させるものであり、これは私にとって非常に制限的なようです。しかし、アプリケーションにそれが必要な理由があるかもしれません。

2
Daniel