オブジェクト指向設計には、パターン、原則、実践など、最初は類似しているか矛盾しているように見える多くの概念があります。実際、それらのほとんどは類似しておらず、矛盾していません。そして、それらを異なって一貫性のあるものにするのは、それらの意図です。
Preserve WholeObjectリファクタリングとCleanCodeTalksビデオで言及されているServiceLocatorパターンとの間に見られる矛盾は、意図と本質は異なりますが、同じ概念として扱われる場合に発生します。
Preserve Whole Objectリファクタリングは、関数への引数の数を減らすことにより、コードを読みやすく、理解しやすく、維持しやすくするために使用される手法です。一方、 Service Locatorは、制御の反転の概念を使用して、システム内のさまざまなコンポーネント間の依存関係を管理するために使用されるデザインパターンです。システムにローカルな影響を与えるPreserveWholeObjectリファクタリング手法(システムのごく一部(関数)に適用される)とは異なり、Service Locatorパターンはシステムにグローバルな影響を及ぼし、より大きなアーキテクチャ上の問題に対処します(依存関係管理)。 )。
Preserve Whole Objectリファクタリングをいつ使用するのですか?
基本的に1つのオブジェクトのプロパティである関数に2つ以上の引数がある場合は、オブジェクト全体のリファクタリングを使用するため、代わりにオブジェクトを渡します。
パラメータオブジェクト(別名引数オブジェクト)(パラメータオブジェクトリファクタリングの紹介)と呼ばれる同様の概念があります。これは、1つのオブジェクトのプロパティではないが、概念的に相互に関連している、または自然に一緒になっているパラメータのグループがある場合、ラップすることを示しています。独自のクラスを使用して、代わりにそのクラスのインスタンスを渡します。これは主に、オブジェクトにメッセージを送信するときに使用されます。
Clean Code、第3章:関数、関数の引数、43ページ(Robert C. Martin)からの引用:
引数オブジェクト
関数に2つまたは3つ以上の引数が必要と思われる場合、それらの引数の一部を独自のクラスにラップする必要がある可能性があります。たとえば、次の2つの宣言の違いについて考えてみます。
Circle makeCircle(double x, double y, double radius);
Circle makeCircle(Point center, double radius);
それらからオブジェクトを作成することによって引数の数を減らすことは、不正行為のように見えるかもしれませんが、そうではありません。変数のグループが一緒に渡される場合、上記の例のxとyのように、それらは、独自の名前に値する概念の一部である可能性があります。
Service Locatorパターンをいつ使用するのですか?
クラスに概念的に関連していない依存関係があり、クラスが具体的な実装に依存することを望まない場合は、 ServiceLocatorパターンを使用します。実際、これは、依存関係管理アプローチのいずれかを使用したい場合です。もう1つの方法は、コンストラクターへの個別の引数としてすべての依存関係を明示的に指定する依存性注入アプローチです。一方、Service Locatorは、すべての依存関係を単一のコンテナーオブジェクトに渡します。実際、これはServiceLocatorパターンとPreserveWholeObjectの非常に類似した点です。混乱の原因となる単一のオブジェクトで引数を組み合わせるリファクタリング。依存関係管理手法は、主にオブジェクトの構築に使用されます。
制御の反転とMartinFowlerによる依存性注入パターンの記事で説明されている依存性管理の両方のアプローチには賛否両論があります。
いつ両方を使用しますか?
クラスに概念的に関連する2つ以上の依存関係があり、それらを1つのオブジェクトに結合し、 ServiceLocatorを使用して依存関係として渡す場合があります。したがって、ご覧のとおり、これら2つの概念は相互に排他的ではありません。