web-dev-qa-db-ja.com

アーキテクチャのベストプラクティス(MVC):リポジトリは直接アクセスされたオブジェクトとオブジェクトメンバーを返すか、リポジトリはオブジェクトメンバーを返します

アーキテクチャ的に言えば、どちらが好ましいアプローチですか(そしてその理由)?

_$validation_date = $users_repository->getUser($user_id)->validation_date;
_
  • メソッド呼び出しによって返されたオブジェクトのメンバーにアクセスすることにより、デメテルの法則に違反しているようです
  • オブジェクトメンバーに直接アクセスすることにより、カプセル化に違反しているようです

$validation_date = $users_repository->getUserValidationDate($user_id);

  • $ users_repositoryがユーザーオブジェクトを返すだけではなくなったため、単一責任の原則に違反しているようです
2
coderabbi

この問題に対処するための技術的に「正しい」方法は、「validation_date」を必要とするメソッド(またはクラス)に正しいUserオブジェクトを渡すことです。可能であれば、必要なオブジェクトを正確に注入する依存関係は、リポジトリ、ServiceLocators、およびファクトリを注入するよりも常に優先されるべきです。必要な最小のコンポーネントは、それを必要とするメソッドに渡す必要があります。問題のコードは、実際にはリポジトリではなくユーザーに依存しています。

質問が示唆するように、コードは検証日にアクセスする必要があるため、これはデメテルの法則違反ではありません。リポジトリは他のオブジェクトへのゲートウェイとしてのみ使用されるため、これはデメテルの法則違反です。

問題の詳細な説明とそれを修正するための最良の方法については、 http://misko.hevery.com/code-reviewers-guide/flaw-digging-into-collaborators/ を参照してください。

2
Tom B

場合によっては、最も直感的なものを選択することが最良の経験則です。

多くの人々は実際にあなたが述べた法律/規則/原則にさえ同意しません。つまり関数型プログラミングは明らかにOOから離れており、データを処理から分離しようとしています。そのような些細なことについては誰もLoDを気にしないと思います。また、単一責任に関するものは、ニースではありますが、難しい場合があります。現実の世界で達成します。

そうは言っても、私見とこの特定の例では、最初の選択肢が最も直接的で直感的だと思います。

1
dagnelies