私は OOP コードを書きながら、エレガント オブジェクトのいくつかのプラクティスを適用します。 そのうちの 1 つは、クラスが final であることです。これは、継承によって拡張することはできず、合成によってのみ拡張できることを意味します。 利点は単純さです。このように、各オブジェクトはまとまりのあるブロックとして見られるということです。クライアントが関心を持っているのは、その露出した動作です。これ以上何もない。代わりに、拡張を通じて、クライアントはそれを破ることができます。 たとえば、オブジェクトはその 2 つのメソッドを相互に関連付けることができます。したがって、そのうちの 1 つを拡張して置き換えることができれば、もう 1 つを壊すことができます。このため、確かに、その実装を確認する必要があります。このようにして、拡張と拡張の間の結合を増やします。 言い換えれば、最終クラスは、公開された動作のみを気にする必要があるという考えを強制します。そして実装ではありません。それにもかかわらず、それは私たちがそれらについてどのように推論するかを変える必要があります. Alias パターンは、この変更の側面を簡素化します。 意図 Alias パターンを使用すると、クラスがオブジェクトをサブクラス化または変更せずに構築できる方法を拡張できます。 動機 いくつかの必須パラメーターを使用してオブジェクトを作成する最終クラスを想定します。オブジェクトを作成する別の方法を追加するにはどうすればよいでしょうか?たとえば、不足しているパラメーターの 1 つ以上にデフォルト値を使用するコンストラクターを追加するにはどうすればよいでしょうか? 1 つの方法は、別のコンストラクターをクラスに追加することです。しかし、これは手に負えなくなる可能性があります。さらに、それは不可能である可能性があります。たとえば、前述の最終クラスは外部ライブラリにある可能性があります。 このアプローチのもう 1 つの欠点は、最終クラスを汚染する可能性があることです。たとえば、JSON を指定してオブジェクトを構築する final クラスを作成できます。しかし、しばらくすると、XML も追加する必要があります。ご想像のとおり、XML を JSON にマップするコードを追加すると、必然的にそのクラスが汚染されます。 ただし、Alias パターンは final クラスに限定されません。たとえば、パラメーターは同じだがセマンティックが異なる 2 つのコンストラクターを使用することはできません。 この問題を解決するには、静的ファクトリ メソッドをクラス コードに追加します。しかし、同じ前述の欠点がこのアプローチに影響を与えます。つまり、これは手に負えなくなります。これは常に可能であるとは限りません。これはクラスを汚染します。 両方の問題に対するより良いアプローチは、目的のコンストラクターの動作を持つ別のクラスを作成することです。このクラスは、独自の構築ロジックをカプセル化します。そして、実際の作成を含め、すべてを他のクラスに委譲します。これが Alias パターンです。 適用性 次の場合に Alias パターンを使用します。 最終クラスのコンストラクターを追加または変更する必要があります。 クラスのコンストラクターを変更またはサブクラス化せずに追加または変更する場合。 変更またはサブクラス化せずに、同じパラメーターを持つクラスのコンストラクターが 2 つ以上必要です。 構造 構造は簡単です。 と Alias Aliased. 参加者 AnInterface インターフェイスを宣言します。 Aliased を実装します。 AnInterface 1 つ以上のコンストラクターを公開します。 Alias を実装します。 AnInterface 1 つ以上のコンストラクターを公開します。 オブジェクトへの参照を維持します。 Aliased 参照された オブジェクトにすべてを委譲します。 Aliased コラボレーション は独自の規則に従って オブジェクトを構築し、その参照を維持します。次に、すべてをエイリアスに委任します。 Alias Aliased 結果 エイリアス パターンには、次の結果があります。 コンストラクターを簡単に追加または変更できます。 継承よりも構成を促進します。 クラスの数が増えます。 反復的な作成を置き換えるために使用すると、コードの重複が減少します。 エイリアス クラスは委任コードを複製します。これが問題である場合は、基本抽象 Alias クラスを使用したアプローチである可能性があります。 実装 Alias パターンを実装するには、次のものが必要です。 インターフェイスを定義します。 クラスで以前に定義されたインターフェイスを実装します。これはエイリアス化されたものになります。 以前に定義したインターフェイスをエイリアス クラスで実装するには、次のものが必要です。 必要に応じてエイリアス化されたオブジェクトを構築するコンストラクターを定義します。 以前に構築されたエイリアス オブジェクトを参照するプライベート インスタンス変数。 エイリアス化されたオブジェクトにすべてを委譲します。 サンプルコード 以下の Java っぽいコードは Alias パターンを表しています。このコードでは、エイリアスは必須パラメーターのデフォルト値を挿入します。 interface AnInterface { void aMethod(); Something anotherMethod(); } final class Aliased implements AnInterface { private final A a; private final B b; Aliased(final A a, final B b) { this.a = a; this.b = b; } void aMethod() { // implementation } Something anotherMethod() { // implementation } } final class Alias implements AnInterface { private final Aliased aliased; Alias(final A a) { this( new Aliased( a, new InstanceOfB(...) ) ); } private Alias(final Aliased aliased) { this.aliased = aliased; } void aMethod() { this.aliased.aMethod(); } Something anotherMethod() { return this.aliased.anotherMethod(); } } 関連パターン ある程度、Alias パターンはオブジェクトの構造を する方法と見なすこともできます。このビジョンは、クラスを、オブジェクトを作成する責任を持つオブジェクトと見なす場合に特に当てはまります。 装飾