003 -02-構造装飾パターン(デコレータ)

I.概要

  また、梱包モードとして知られているデコレーション(デコ)モード、。透過的にクライアントによってオブジェクトの機能を拡張するために、関係を継承するための代替です。彼はまた、Decoratorパターンとして知られている23個のデザインパターン、英語と呼ばれるDecoratorパターンの一つです。元のクラスファイルを変更し、継承を使用することなく、装飾的なパターンの場合には、動的オブジェクトの機能を拡張します。これは、実際のオブジェクトをラップするために飾られているラッパーオブジェクトを作成することです。

  オブジェクトと、元のオブジェクトを変更せずに、動的にいくつかの追加の責任を追加します。

1.1アプリケーションのシナリオ

  • クラスまたはクラスの拡張は、追加の責任を追加します
  • オブジェクトは動的関数に追加され、これらの機能を動的に再失効することができ
  • サブクラス拡張することを生成する際の方法を用いることができません。あるケースでは、サブカテゴリーの多数を生成するそれぞれの組み合わせをサポートするために別々の拡張の多数存在することができるように、サブクラスの数は爆発的な成長。クラス定義のクラスまたはサブクラスの定義を生成するために使用することができないので、別の状況は隠すことができます。
  • これは、継承は非現実的になるように、生成された順列と基本機能の特徴の組み合わせの非常に大きな数で増加させる必要があります。

  たとえば、次のように非常に深いjavaはI / Oクラスに反映さがあります。

注、

  1.多目的組成物を、以下の継承。
    デザインサブクラスが動作を継承使用して、静的にコンパイル時に決定され、そしてすべてのサブクラスは、同じ動作を継承します。我々は、オブジェクトを拡張し、行動の実践を組み合わせて使用​​することができますしかし、もし、それが実行時に動的に拡張することができます。
  2.クラスは、拡張のために開いているように設計されたが、修正のために閉鎖されなければなりません。

1.2、長所と短所

  利点

    継承の目的1. Decoratorパターンは、オブジェクトの機能を拡張することであるが、デコレータは継承よりも柔軟性を提供することができます。
    2.異なる順列及びこれらのクラスや装飾コンクリートの装飾の組み合わせを使用することにより、設計者は、異なる行動の組み合わせの多くを作成することができます。

  短所

    1.これは、継承された特性よりも柔軟性があり、またそれより多くの複雑さを意味します。
    2.装飾パターンは、多くのサブカテゴリにつながる可能性使い古された場合、プログラムは非常に複雑になり、設計に表示されます。
    3.装飾パターンは、抽象コンポーネント(部品)のタイプにプログラムされています。あなたが特定のコンポーネントのためにプログラムしたい場合は、アプリケーションのアーキテクチャを再考すべきである、とデコレーターが適切です。もちろん、あなたが「半透明、」Decoratorパターンを達成するために、新しい公共の振る舞いを追加して、コンポーネントのインタフェースを変更することができます。実際のプロジェクトでは、最良の選択をしたいです。
    4.小さなオブジェクト、小さなオブジェクトによって占有されていたメモリを大量に生産ある程度のパフォーマンスに影響を与えます。

1.3、クラス図の役割と責任

  

  役割と責任の装飾パターン:

  1は、抽象コンポーネントの文字(コンポーネント):抽象インタフェース、インタフェースは、親クラスと飾らの装飾です。(車)

  図2に示すように、特定の構成要素の役割(ConcreteComponent) 抽象クラス実装部品。(RunCar)

  図3は、抽象装飾的役割(デコレータ):コンポーネントへの参照が含まれており、一貫性の抽象コンポーネントインタフェースを定義します。(CarDecorator)

  4、特定の装飾的な役割(ConcreteDecorator) 実装クラスは抽象装飾的な役割です。特定の装飾を担当。(FlyCarDecorator、SwimCarDecorator)

1.4進化

1.4.1、オリジナルの道

  私たちは、このような機能を実現する車の異なるさまざまな機能を構築する場合は、次のようになる前に、それが実装されています。

  まず、)車のインタフェースは、それが(実行を実行することで、すべての車両の基本的な機能を定義して作成し、(その機能のショーを表示する方法)、

インタフェースカー 

パブリックインターフェイスカー{ 
    無効ショー(); 

    無効実行(); 
}

  その後、車のインタフェースを実現するために、各特定の車両を作成します

  クラスの基本機能 - 実行されます

パブリッククラスRunCarは車{実装

    @Override 
    公共ボイドショーを(){ 
        this.run(); 
    } 

    @Override 
    公共ボイドラン(){ 
        System.out.printlnは( "可以跑")。
    } 
}

  スイム車

パブリッククラスSwimCarは{車を実装

    @Override 
    公共無効ショー(){ 
        this.run(); 
        this.swim(); 
    } 

    @Override 
    公共ボイドラン(){ 
        System.out.printlnは( "可以跑")。
    } 

    公共ボイドSWIM(){ 
        System.out.printlnは( "可以游泳")。
    } 
}

  空飛ぶ車

パブリッククラスFlyCarは車{実装

    @Override 
    公共ボイドショーを(){ 
        this.run(); 
        this.fly(); 
    } 

    @Override 
    公共ボイドラン(){ 
        System.out.printlnは( "可以跑")。
    } 

    公共ボイドフライ(){ 
        System.out.printlnは( "可以飞")。
    } 
}

  テスト

    @Test 
    公共ボイドtestCar(){
         //         車の車= 新しいRunCar();
//         車の車= 新しいFlyCar(); 
        車の車= 新しいSwimCar(); 
        カーショー(); 
    }

このように、各車両に新しい、すべての新しい機能と同等のものを他のクラスまたはインタフェースを実装または拡張新しいサブクラスを書き込む必要があり、それは新しい車が必要です。

1.4.2、装飾的なパターン

  まず、上記と同様の両方、なぜなら限り、車は関数を実行している必要がありますように、新しいカーポート、およびカークラスRunCarの基本的な実装を作成します

  次に、新しい装飾、異なる機能に異なる装飾で構築

  1、車のインタフェースを実装する新しい装飾親クラス、コンストラクタ引数を提供し、一般的な方法は、(見せる)、車のプライベートメンバ変数、およびそれらを()、set()メソッドを取得し提供します。

  なぜなら、装飾、または車の後、車を継承するようにしてください

パブリック抽象クラスCarDecoratorは車{実装
    プライベートカーの車を。

    公共CarDecorator(車車){ 
        this.car = 車。
    } 

    公共車getCar(){
         戻り車。
    } 

    公共ボイド関数setcar(車車){ 
        this.car = 車。
    } 

    パブリック抽象ボイドショー(); 
}

  異なる装飾新しい装飾、抽象クラスと継承CarDecoratorのための2、

  (1)水泳は、装飾的な抽象メソッド、ユニークで新しい方法をカバー

パブリッククラスSwimCarDecoratorはCarDecorator {拡張

    公共SwimCarDecorator(カー車){ 
        スーパー(車を)。
    } 

    @Override 
    公共ボイドショー(){ 
        this.getCar()を表示()。
        this.swim(); 
    } 

    公共ボイドSWIM(){ 
        System.out.printlnは( "可以游泳")。
    } 

    @Override 
    公共ボイドラン(){ 
    } 
}

  (2)飛行装飾

パブリッククラスFlyCarDecoratorはCarDecorator {拡張

    公共FlyCarDecorator(カー車){ 
        スーパー(車を)。
    } 
    @Override 
    公共ボイドショー(){ 
        this.getCar()を表示()。
        this.fly(); 
    } 

    公共ボイドフライ(){ 
        System.out.printlnは( "可以飞")。
    } 

    @Override 
    公共ボイドラン(){ 
    } 
}

テスト

    @Test 
    公共無効getCar(){ 
        車の車= 新しいRunCar(); 
        カーswimCar = 新しいSwimCarDecorator(車)。
        swimCar.show(); 
    }

  このように、機能を追加し、装飾的な、すべての新機能は新しい車ではなく、むしろ、これは最も基本的な車、基本的な車に基づいて装飾同等RunCarの基本であることに等しいではありませんこの基本的な車。

  車で変数を作成するために、そう装飾、または車の後に、私たちが直接車swimCar =新しいSwimCarDecorator(車)ことができるので、車を継承するようにしてください。 

  車はすでに泳ぎを持っているし、機能を飛ぶ場合は同様に、継承は、すべての機能は、新しいサブカテゴリーを追加する必要がある場合は、その後も新しいの新しい水泳や空飛ぶ車、継承の必要性がありサブクラスは、装飾的なパターンはRunCarに基づいて変更され、新たなものを、必要としないながらも、2つの機能を有している二回することができます。このように:

    @Test 
    公共無効getCar2(){ 
        車の車= 新しいRunCar(); 
        カーswimCar = 新しいSwimCarDecorator(車)。
        カーflySwimCar = 新しいFlyCarDecorator(swimCar)。
        flySwimCar.show(); 
    }

  この方法では、最終的flySwimCarは、それはまた、この装飾は、コンストラクタにパラメータとして使用することができますように、車の装飾クラスの継承の理由である、飛行、水泳の機能を有しています。

   

1.5、関連するデザインパターン

デコレータモードとプロキシモード

  • Decoratorパターン:オブジェクトの動的な追加方法に焦点を当てます。
  • プロキシモード:オブジェクトへのアクセスを制御するための注意、プロキシパターンプロキシクラスは、顧客のオブジェクトの特定の情報を非表示にすることができます。
  • 使用時にはプロキシモードの時、多くの場合、プロキシオブジェクトにオブジェクトのインスタンスを作成します。私たちが使用している場合Decoratorパターンを、元のオブジェクトは、通常のパラメータは、コンストラクタのデコレータに渡されますよう

装飾的なパターンとAdapterパターン

  • 装飾的なパターンとAdapterパターンは、梱包モードと呼ばれています。デコレータモードでは、デコレータデコレータと同じインタフェースを実装し、またはデコレータはデコレータのサブクラスであることができます。アダプタモードでは、インターフェイス一致の部分を有することも、適応クラスは、もちろん、異なるインターフェースを有するクラスに可能なように構成されています。

第二に、拡張

2.1、デコレーターでJDK

2.1.1、JavaのI / O- リーダー与java.io.BufferedReader

リーダー

パブリック抽象クラスのリーダーが読み取り可能、開閉可能な{実装して
    保護されたオブジェクトのロックを。
    保護リーダー(){ 
        this.lock = この; 
    } 

BufferedReaderの

パブリッククラスBufferedReaderのリーダー{拡張

    プライベートリーダーでは

    プライベートchar型の CB [] ; 
    プライベートint型nChars、nextChar。

    プライベート静的最終int型に無効化=  - 2 
    プライベート静的最終int型無印=  - 1 ; 
    プライベートint型 markedChar = マークされていません。
    プライベートint型 readAheadLimit =  0 ; 

    プライベートブールskipLF = 偽;

    プライベートブールmarkedSkipLF = 偽; 

    プライベート静的int型 defaultCharBufferSize =  8192 ; 
    プライベート静的int型 defaultExpectedLineLength =  80 ;
    公共 BufferedReaderの(リーダーint型 SZ){

Readerデコレータは、あるBufferedReaderデコレータです

2.1.2、JavaのI / O- のInputStream与FilterInputStream

  

InputStreamデコレータは、あるFilterInputStreamデコレータです

以下は、入力ストリーム Decoratorパターンは、クラス図を反映しています。

  

2.2、Springアプリケーション

2.2.1、TransactionAwareCacheDecorator

  

2.2.2、春のセッション

  org.springframework.session.web.http.SessionRepositoryFilter.SessionRepositoryRequestWrapper

2.3、Tomcatの

2.3.1、javax.servlet.ServletRequestWrapperで

   

2.4、mybatis

2.4.1、org.apache.ibatis.cache.Cache

  

 

おすすめ

転載: www.cnblogs.com/bjlhx/p/11198949.html