装飾的なパターンの定義
装飾的な定義(デコレータ)モード:既存の状況を変更せずにオブジェクト構造を指し、動的オブジェクトは、オブジェクト構造スキーマに属する関数の数(すなわち、その付加機能を増大させる)モードを、増加させることです。
第二に、装飾的なパターンの長所と短所
デコレーション(デコ)モードの主な利点は以下のとおりです。
- 装飾されたスキーマ拡張オブジェクトは、継承を使用するよりも、より柔軟に機能します。
- あなたは、いくつかの異なる動作の組み合わせを作成し、異なる装飾コンクリートの数を設計することができます。
主な欠点は以下のとおりです。
使い古さ手続きが非常に複雑になります場合は装飾的なパターンは、サブ・カテゴリの数を増加させました。
第三に、装飾的なパターンを達成するために
典型的には、クラス延ばす機能が、継承を使用して実装されます。継承しかし、静的特徴を有する高結合、および伸長の増加と、それはサブクラスを拡張します。あなたが実際のオブジェクトをラップするラッパーオブジェクト(すなわち、装飾品)を作成するために、関係の組み合わせを使用する場合は、装飾模様の目標である付加的な機能を提供する、クラス構造を変更することなく、実際のオブジェクトを維持しました。次の基本的な構造と実装を分析します。
装飾的なパターンは、主に次の役割が含まれています。
- 抽象コンポーネント(部品)の役割:追加の責任を受信する準備ができてオブジェクトを調節するために抽象インタフェースを定義します。
- 特定のコンポーネント(コンクリートコンポーネント)役割:装飾的な役割によって、その責任の一部を追加し、抽象コンポーネントを達成します。
- 抽象装飾(デコレータ)役割:抽象メンバを継承し、そして特定の部材の例を含む、特定のメンバ関数は、そのサブクラスによって拡張することができます。
- 具体的な装飾(ConcreteDecorator)役割:実装依存方法抽象的な装飾、および特定のメンバーオブジェクトに追加の責任を追加します。
示されるように、図装飾的なパターン形状:
レッツは、このような、これが例の用途パンケーキ、フルーツは、コードは以下のとおりであるとして、この実装の継承プロパティを通じて、私たちの新しい方法を見てみましょう:
/ ** *パンケーキ * / パブリック クラスBattercake { 保護された文字列getDesc(){ 戻り "パンケーキ" ; } 保護 int型のコスト(){ リターン 8。; } } / ** *パンケーキと卵 * / パブリック クラス BattercakeWithEgg 延びBattercake { @Override パブリックストリングgetDesc(){ リターン スーパー .getDesc()+ "卵を追加" ; } @Override 公共 int型のコスト(){ リターン スーパー .cost()+ 1 ; } } / ** ソーセージのパンケーキと卵* * / パブリック クラス BattercakeWithEggSausageは延びBattercakeWithEgg { @Override パブリックストリングgetDesc(){ リターン スーパー .getDesc()+ "プラスソーセージ" ; } @Override 公共 int型のコスト(){ リターン スーパー()+ 2 .cost ; } } パブリック クラスのテスト{ 公共 静的 ボイドメイン(文字列[]引数){ Battercake battercake =新しいBattercake(); System.out.println(battercake.getDesc() + "销售价格:" + battercake.cost())。 Battercake battercakeWithEggは = 新しいBattercakeWithEggを(); System.out.println(battercakeWithEgg.getDesc() + "销售价格:" + battercakeWithEgg.cost())。 Battercake battercakeWithEggSausageは = 新しいBattercakeWithEggSausageを(); System.out.println(battercakeWithEggSausage.getDesc() + "销售价格:" + battercakeWithEggSausage.cost())。 } }
最後に、テストの結果:
パンケーキ販売価格:8つの パンケーキプラス卵の販売価格: 9つの パンケーキプラス卵プラスソーセージ販売価格: 11
我々は拡張クラスを実現し、高い継承と相まって、あなたは元のクラスを変更する場合、新しいクラスは、無限に増加する場合は、装飾的なパターンを使用する場合、クラスの背中に大きな影響は、そう、として次の中:
パブリック クラスDecoratorPattern { 公共 静的 ボイドメイン(文字列[]引数) { コンポーネントP = 新しい新しいConcreteComponent(); p.operation(); のSystem.out.println(「-------------- ------------------- " ); 成分D = 新しい新しいConcreteDecorator(P); d.operation(); } }
// 抽象コンポーネント役割 インターフェース コンポーネント { 公共 ボイド動作(); }
// 特定の役割メンバ クラス ConcreteComponent実装部品 { パブリックConcreteComponent() { System.out.printlnは( "の役割は、特定のコンポーネントを作成します。" ); } 公共 ボイド動作() { System.out.printlnは( "メソッド呼び出し特定のロール部材の操作()" ); } }
// 抽象装飾文字 クラスデコレータ実装部品 { プライベートコンポーネントコンポーネント; 公共デコレータ(コンポーネントコンポーネント) { この .component = コンポーネント; } 公共 ボイド動作() { component.operation(); } }
// 詳細な装飾文字 クラス ConcreteDecorator 延びデコレータ { 公共ConcreteDecorator(コンポーネントコンポーネント) { スーパー(成分); } 公共 ボイド動作() { スーパー.operation(); addedFunction( ); } 公共 ボイドaddedFunction() { System.out.printlnは( "特定のメンバーの役割のaddedFunction追加機能()" ); } }
アプリケーションシーン四、装飾的なパターン
そのアプリケーション・シナリオ説明装飾パターンについて上記説明の構造及び特性は、装飾的なパターンは、一般的に次のような状況で使用されています。
- 既存のカテゴリに追加機能を追加することが望まれるが、この方法は、サブクラスを生成するように拡張することができるとき。例えば、クラスが隠されているか、クラスが究極のクラスがある場合、または継承を使用すると、サブカテゴリーの多くを生成します。
- 継承を使用して、順列と組み合わせの基本的な機能のセットを介して既存の機能の多くを生成することが望まれるとき、達成することは困難であり、モデルは非常に良い達成飾られています。
- オブジェクトが動的機能要件を追加することができるとき、それは、次いで、動的に引き出されてもよいです。
のJavaのI / O標準ライブラリよりもJava言語設計の装飾的なパターンの中で最も有名なアプリケーション。例えば、のInputStreamのサブクラスFilterInputStream、OutputStreamのサブクラスFilterOutputStream、BufferedReaderのリーダーとFilterReaderのサブクラスは、作家がBufferedWriterの、FilterWriterとのPrintWriterなどがサブクラス化し、彼らは抽象的な装飾がされています。
次のコードは、装飾BufferedReaderのFileReaderの一例である使用バッファを増やします。
IN = BufferedReaderの新しい BufferedReaderの(新しい FileReaderの(「filename.txtn)); 文字列S = in.readLine()。
V.装飾模様が広がります
装飾的なパターンは、4つの役割は、パターンは、以下の2つのケースとして、簡略化することができるいくつかの環境では、任意の時点で存在しない含ま。
- 。特定のメンバーだけでなく、抽象メンバである場合、継承は、具体的には、図に示す構造を抽象装飾部材を使用できます
- のみ特定の装飾、抽象および具象内装の装飾を組み合わせてもよい場合、構造は、図に示されています。