デコレータはアダプタよりもクライアントに対して透過的であり、ネストされた装飾を可能にするのはこの透過性であると読みました。この文脈での透明性とは実際にはどういう意味ですか?
PS:私はこれらのデザインパターンの両方を知っています。したがって、その前提に基づいて答えを出すことができます。
デコレータはアダプタよりもクライアントに対して透過的であり、ネストされた装飾を可能にするのはこの透過性であると読みました。この文脈での透明性とは実際にはどういう意味ですか?
PS:私はこれらのデザインパターンの両方を知っています。したがって、その前提に基づいて答えを出すことができます。
デコレータは、指定されたタイプAのオブジェクトを取得し、それを同じタイプAのオブジェクトにラップします。クライアントは、同じタイプであるため、実際のオブジェクトを使用しているかのように装飾されたオブジェクトを使用できます。
アダプタは、特定のタイプAのオブジェクトを受け取り、それを別のタイプBのオブジェクトにラップします。元のタイプAを使用したクライアントは、他のタイプBを使用するように適合させる必要があります。
とはいえ、アダプタパターンを使用する場合、それはクライアントがタイプBのオブジェクトを必要とし、タイプAのオブジェクトしかないためです。そこで、アダプタにラップしてタイプBのオブジェクトにします。
2つのパターンは同じ原理(ラッピング)を使用しますが、目的は異なります。元のオブジェクトの動作を変更するデコレータ。タイプを変更するためのアダプター。
デコレータと装飾されたオブジェクトの使用にクライアントの違いはありません(どちらも同じインターフェイスを持っています)。したがって、デコレータは透過的です(つまり、クライアントには見えません)。デコレータは他のデコレータで装飾することもできます-それはクライアントに影響を与えません。クライアントはまだ彼が装飾されたオブジェクトで作業していると考えることができます。
素敵なサンプルですStreams
。任意の数のデコレータ(ジッピング、暗号化、バッファリング)でデコレートされたストリームを渡すことができますが、これらのデコレータは、ストリームを使用するすべてのクライアントに対して非表示のままになります。
実際、アダプターが透過的であると見なすことができる理由がわかりません。クライアントはアダプターのタイプを知らないはずです。また、インターフェースが異なるため、クライアントはアダプターをアダプターとして扱うことはできません。
デコレータがどのように透過的であるかを答えるのは、アダプタが卑劣で乱暴な理由よりも簡単です。デコレータは、より頻繁にマス機能にネストされる傾向があります(これは、多くの場合直交しています。たとえば、BufferedFileWriterはバッファリングを追加しますが、これはクラスのラッピングの基本操作を実際には変更しません。それらを元に委任します)。通常、デコレータは元のインターフェイスでそれ自体をクローキングしているため、デコレータが何をしているかを簡単に確認できます。
アダプターも同様に透過的にすることができます。アダプターのネストがより難しい理由は、状態オブジェクトの変換について話しているからだと思います。次に、それが意味するすべての醜さをすばやく理解します(MVCが成長するにつれて発生することの1つ)。たとえば、私は古いアプリを持っていて、たくさんの入力を与えられたときにリスク評価を与えてくれます。それを使用したい新しいWebインターフェースがありますが、別の形式のデータが必要です。元のコードを変更することはできないため、変換するアダプターを導入します。それは何を翻訳していますか?一般的にいくつかの状態表現。したがって、インターフェイスが異なる場合は、入力を取得して変換し、再調整します。出力をさらにマッサージする必要がある場合は、同上。複数のアダプターをレイヤー化する場合、
デコレータは通常、このような翻訳ジョブには使用されませんが、コードがないもの、または新しい機能が直交しているものの機能を補足するために使用されます。したがって、ユーザーはユーザーを使用できます。または、1つ以上のデコレータを使用しないでください。