学習記録:「C ++の設計パターン - 李Jianzhongスピーカー」4「シングル責任」モード

シングル責任モード:責任分担が明確でない場合は、重複コードの完全な、この時間は、キー責任引き分けている間のソフトウェア・コンポーネントの設計では、結果は多くの場合、需要が変化し、サブカテゴリーの急速な拡大と継承を使用することによって得られます。

典型的なパターン:装飾的なパターン(デコレータ)、ブリッジモード(ブリッジ)。

装飾的なパターン

1.動機

いくつかのケースでは、我々は、この拡張モードが柔軟性のないなって、導入されたタイプの継承の静的な性質のために、「目的関数を拡張するために過度の使用継承」であってもよく、そして増加した(増加サブクラスの拡張)、組み合わせ(拡張機能の組み合わせ)膨張複数のサブクラスの様々なサブクラスをもたらします。

2.役割

必要に応じて、「拡張オブジェクト関数は、」動的に実現することができる。避けながら「増加に拡張機能を、」サブクラスの拡張の問題はそれほど任意「拡張子が変化」という最小限に抑える衝撃によるもたらさ。

3.定義

オブジェクトへの動的(組み合わせ)は、いくつかの追加の責任を追加します。サブクラス(継承)を生成Decoratorパターンよりも柔軟性が増加機能、のために(重複コードの除去を、サブクラスの数を減らします)。

4.コード

//既存のコード。
//事業運営
クラスストリーム{
公共
    仮想文字読み取り(int型の数)= 0 ;
    仮想ボイド(int型の位置)= 0を求めます 仮想空の書き込み(charデータ)= 0 ; 〜仮想ストリーム(){}}; // FileStreamを主要なクラスのクラス:公共ストリーム{パブリック:読む仮想CHAR(int型数値){//読み込みストリームファイル}仮想無効シーク(int型の位置){//ファイルストリームが置か仮想}書き込みボイド(文字データ){//書き込みファイルストリーム}}; NetworkStreamクラス:パブリック・ストリーム{パブリック:// ... };のMemoryStreamクラス:パブリック・ストリーム{パブリック:// ... }; //拡張操作クラスCryptoFileStream:公共FILESTREAM {パブリック:仮想文字を読んで(INT 番号){//追加の暗号化操作... FILESTREAM ::読み取り(番号); // 読み込みストリームファイル}仮想のボイド(int型のシーク位置を){//余分暗号化... FILESTREAM ::(位置)をシーク; // ファイルストリーム位置}仮想無効書き込み(バイトデータ){//追加の暗号化操作...のFileStream ::書き込み(データ); // ファイルストリームを書く}};クラスCryptoNetworkStream ::公共NetworkStream {パブリック:// ... }; CryptoMemoryStreamクラス:公共のMemoryStream {公共:// ... }; //追加のバッファリング動作クラスBufferedFileStream ...:公共のFileStream {// ... }; BufferedNetworkStreamクラス:公共NetworkStream {// ... }; BufferedMemoryStreamクラス:公共のMemoryStream { // ... } //追加の暗号化操作は...クラスCryptoBufferedFileStreamをキャッシュ:公共のFileStream {パブリック:読む仮想CHAR(int型数値){// ... //余分な暗号化操作、追加のバッファリング動作... FILESTREAM ::読み取り(番号); //読み込みストリームファイル}仮想無効シーク(int型位置){// ... //余分な暗号化操作、追加のバッファリング動作...のFileStream ::(位置)をシーク; // 位置ファイルストリーム}仮想無効バイト書き込み(データ){//追加の暗号化操作。追加のバッファリング動作... // ... FILESTREAM ::書き込み(データ); // ファイルストリームを作成し、ボイド;}} //コンパイルするときのプロセス(){CryptoFileStream * FS1 =新しいアセンブリCryptoFileStreamを(); BufferedFileStream * FS2 =新しい新しいBufferedFileStream(); FS3 = * CryptoBufferedFileStream新しい新しいCryptoBufferedFileStream();}
//装飾パターンコードを使用します
//事業運営
クラスストリーム{
公共
    仮想文字読み取り(int型の数)= 0 ;
    仮想ボイド(int型の位置)= 0を求めます 仮想空の書き込み(charデータ)= 0 ; 〜仮想ストリーム(){}}; // FileStreamを主要なクラスのクラス:公共ストリーム{パブリック:読む仮想CHAR(int型数値){//読み込みストリームファイル}仮想無効シーク(int型の位置){//ファイルストリームが置か仮想}書き込みボイド(文字データ){//書き込みファイルストリーム}}; NetworkStreamクラス:パブリック・ストリーム{パブリック:// ... };のMemoryStreamクラス:パブリック・ストリーム{パブリック:// ... }; //拡張操作DecoratorStream :パブリックストリーム{保護:*ストリームのストリーム; // ... DecoratorStream(ストリーム* STM):ストリーム(STM){}}; CryptoStreamクラス:パブリックDecoratorStream {パブリック:CryptoStream(ストリーム* STM):DecoratorStream(STM){ }仮想文字読み取り(int型数){//追加の暗号化操作...合理化>読む(番号); // 読み込みストリームファイル}無効仮想シーク(int型の位置){//追加の暗号化操作...ストリーム::シーク(ポジション) ; //ファイルストリームが配置}(バイト書き込み無効仮想データ){//追加の暗号化操作...ストリーム::書き込み(データ); //はファイルストリームを書く}}; BufferedStreamクラス:公共DecoratorStream {*ストリームstream;公共... @ :BufferedStream(ストリーム* STM):DecoratorStream(STM){// ...} };ボイドプロセス(){//フィットランタイム新しい新しい= S1 *のFileStream のFileStream(); * S2 = CryptoStream新しい新しいCryptoStream(S1); BufferedStream * S3 =新しい新しいBufferedStream(S1); CryptoBufferedFileStream * S4 =新しい新しいBufferedStream(S2);}

 5.解析

       これは、余分な機能の外に延び、(検索)を配置し、書き込み機能、読み取った、そこにファイルストリーム、メモリ、ネットワークフローと業務フローがあるので、上で、コンテンツストリームプログラムで暗号化し、キャッシュ操作が含まれます。

       方法に元のコードでこれらの機能を拡張する継承、それはまた、十分詳細に理解するが、以下の問題:継承された静的な品質の導入、この拡張モードが柔軟性のない製造、および増加した(拡張サブクラス増加)、種々のサブクラスの組み合わせは、図の下に示される複数の拡張サブクラスを引き起こすであろう。mは、関数の2つの種類、プログラム(1 + N + X)クラスの合計が、nの関数を考えます。(反射Xは、どのようにn及びmによって表します)。

       追加の責任を高めることを目的に(組み合わせて)動的によってコード装飾模様の使用時に、構造は、図1に示す。、プログラム(1 + N + 1 + M)のクラスの合計よりもクラスの数が大幅に削減される前に、ダイナミック組成物は、ランタイムコンパイル時の依存関係に依存するであろう。

6.構造

ここで、(例えばストリームとして抽象クラス、)コンポーネント:

      オブジェクトのインタフェースを定義します。1.動的にこれらのオブジェクトの責任に追加することができます。

ConcreteComponent(例えばFileStreamを、NetworkStreamとして具象クラス)

      オブジェクトを定義1.、あなたは、このオブジェクトにいくつかの責任を追加することができます

デコレーター(例えばDecoratorStreamなどの装飾抽象クラス、)

      1.コンポーネントは、オブジェクトへのポインタへのポインタを維持し、一貫性のあるインタフェースコンポーネントとのインターフェースを定義します。

(例えばCryptoStream、BufferedStreamとして装飾コンクリート)ConcreteDecorator

      職務にコンポーネントを追加します。1.

7.まとめ   

     技術の組み合わせを使用することによって1は、実行時に動的にオブジェクトの機能を拡張する能力を達成するために、Decoratorパターンを継承しない、必要に応じて複数の機能を拡張することができます。「柔軟性に欠ける」とによって引き起こされる継承の使用は避けてください「マルチサブクラス波及効果を。」

     インターフェースクラスの継承関係の2.Decorator性能があるコンポーネント、すなわちデコレータクラス継承コンポーネントクラスは、インターフェイスを有しています。しかし関係で、すなわちデコレータターンは、別のコンポーネントクラスを使用し、パフォーマンスの組み合わせとして実装され、HAS-コンポーネント。

     「装飾的」手段方法 - 3.Decoratorオブジェクトモデルは、問題「マルチサブクラスが多重継承を誘導された」解決しない、デコレータモードアプリケーションの要旨「は、複数の方向に主要クラスの拡張」を解決することです。

第二に、ブリッジモード

1.動機

固有ロジックのいくつかのタイプのため、彼らは、2つの変寸法、及び緯度の変化であっても、複数を有するように実装。

2.役割

両者が容易これに対処するために追加の複雑さを導入することなく、さらに複数の方向に沿って変化することができるように入力し、「多次元変化。」

3.定義

抽象化(ビジネス機能)と部品(プラットフォーム)を実装するには、彼らが独立して変化させることができるように、分離しました。

4.コード

//既存のコード。
クラスメサジェ{
公共
    仮想空ログイン(文字列名、文字列のパスワード)= 0 ;
    仮想ボイドのSendMessage(ストリングメッセージ)= 0  仮想空SendPicture(画像イメージ)= 0 ; 仮想空PlaySound()= 0 ; 仮想のボイド行うdrawShape()= 0 ; 仮想空WRITETEXT()= 0 ; 仮想空の接続()= 0 ; 仮想〜メサジェ(){}}。//平台实现クラスPCMessagerBase:公共メサジェ{パブリック:仮想ボイドPlaySound(){// ********** }仮想ボイド行うdrawShape(){// ********** }仮想ボイドWRITETEXT(){// ********** }仮想ボイド接続(){// ********** }}。クラスMobileMessagerBase:公共メサジェ{パブリック:// ********** }。//业务抽象クラスPCMessagerLite:公共PCMessagerBase {パブリック:仮想空ログイン(文字列名、文字列パスワード){PCMessagerBase ::接続(); }仮想ボイドのSendMessage(文字列メッセージ){PCMessagerBase :: WRITETEXT()。}仮想ボイドSendPicture(イメージ画像){PCMessagerBase ::行うdrawShape()。}}。クラスPCMessagerPerfect:公共PCMessagerBase {パブリック:仮想空ログイン(文字列名、文字列のパスワード){PCMessagerBase :: PlaySound(); PCMessagerBase ::接続(); }仮想ボイドのSendMessage(文字列メッセージ){PCMessagerBase :: PlaySound()。PCMessagerBase :: WRITETEXT(); }仮想ボイドSendPicture(イメージ画像){PCMessagerBase :: PlaySound()。PCMessagerBase ::行うdrawShape(); }}。クラスMobileMessagerLite:公共MobileMessagerBase {パブリック:// ********** }。クラスMobileMessagerPerfect:公共MobileMessagerBase {公共:// ********** };ボイドプロセス(){アセンブリメサジェ* M =新//コンパイル時MobileMessagerPerfect();}
//ブリッジモードコードを使用
クラスメサジェ{
保護されました
     MessagerImp * messagerImp; // ...
公共
    仮想空ログイン(文字列名、文字列のパスワード)= 0 ; 仮想ボイドのSendMessage(ストリングメッセージ)= 0  仮想空SendPicture(画像イメージ)= 0 ; 仮想〜メサジェ(){}}。クラスMessagerImp {パブリック:仮想ボイドPlaySound()= 0 ; 仮想のボイド行うdrawShape()= 0 ; 仮想空WRITETEXT()= 0 ; 仮想空の接続()= 0 ; 仮想MessagerImp(){}}。//平台实现NクラスPCMessagerImp:公共MessagerImp {パブリック:仮想ボイドPlaySound(){// ********** }仮想ボイド行うdrawShape(){// ********** }仮想ボイドWRITETEXT(){// ********** }仮想ボイド接続(){// ********** }}。クラスMobileMessagerImp:公共MessagerImp {パブリック:// **********}。//业务抽象M //类的数目:1 + N + M個のクラスMessagerLite:公共メサジェ{パブリック:仮想ボイドログイン(文字列名、文字列のパスワード){messagerImp-> 接続(); }仮想ボイドのSendMessage(文字列メッセージ){messagerImp-> WRITETEXT(); }仮想ボイドSendPicture(イメージ画像){messagerImp-> 行うdrawShape(); }}。クラスMessagerPerfect:公共メサジェ{パブリック:仮想空ログイン(文字列名、文字列のパスワード){messagerImp-> PlaySound(); messagerImp-> 接続(); }仮想ボイドのSendMessage(文字列メッセージ){messagerImp-> PlaySound(); messagerImp-> WRITETEXT(); }仮想ボイドSendPicture(イメージ画像){messagerImp->音を出す(); messagerImp-> 行うdrawShape(); }}。ボイドプロセス(){//运行时装配MessagerImp * MIMP =新しいPCMessagerImp()。メサジェ* M =新メサジェ(MIMP)。}

 5.解析 

        これは、異なるプラットフォーム(PCと機動)、異なるサービス(MessagerLite、MessagerPerfect)の上のプログラムについてです。

        オリジナルコードと元のコードは、機能を拡張するための継続的連続を通じて同様の装飾的なパターンですが、欠点は、それはおそらく巨大な柔軟なサブクラスを引き起こすことはありませんが、明らかです。

        ブリッジモードでは、抽象(ビジネス機能)と部品(プラットフォーム)分離を実施し、そのような抽象を使用してコード内のそれぞれの次元に沿って達成するために変更されてもよいです。

6.構造

 その中でも、     

       1.Abstraction:抽象クラスインターフェースを定義し、Implementtor型ポインタのオブジェクトへのポインタを維持します。

       2.RefinedAbstraction:抽象によって定義されたインタフェースの拡張。

       3.Implementor:正確にも完全に異なっていてもよい抽象インタフェースと一致する必要はないインタフェースの実装クラスを定義します。

       4.ConcreteImplementor:実装者がインタフェースを実装し、その実装を定義します。

7.まとめ

       抽象そのような抽象の実装と実現の間の結合固有デカップリング「オブジェクト間の組み合わせの関係」を用い1.Bridgeモードは、各次元に沿って変化してもよいです。抽象と呼ばれ、その「サブクラス」、すなわち、その緯度に沿って変更を実装します。

       、貧しい再利用性(すなわち、クラスは変更のために一つだけの理由があります)時々2.Bridgeモードは、多重継承の仕組みに似ていますが、多重継承方式は、多くの場合、単一責任の原則に反しています。ブリッジモードでは、複数の継承制度のソリューションよりも優れています。

       アプリケーション3.Bridgeパターンは、時にはクラスが二つ以上の寸法変化が、その後、あなたは橋拡張モードを使用することができ、一般的に「非常に強力な2次元の変化」です。

おすすめ

転載: www.cnblogs.com/gql-live-laugh-love/p/11922336.html