何人かの著者がこれをほのめかしましたが、私はその点が十分に明確にされていないと思ったので、私は答えを追加しようと思いました。
PIMPLの主な目的は、N*M問題を解決することです。この問題は他の文献で他の名前を持っているかもしれませんが、簡単な要約はこれです。
ある種の継承階層があり、階層に新しいサブクラスを追加する場合は、N個またはM個の新しいメソッドを実装する必要があります。
私は最近これに気付いたばかりであり、私自身の承認により、まだこれについての専門家ではないので、これはおおよその手に負えない説明にすぎません。
なされた既存のポイントの議論
しかし、私はこの質問と数年前に同様の質問に出くわしました、そして私は与えられた典型的な答えに混乱しました。(おそらく、私は数年前にPIMPLについて最初に学び、この質問とそれに類似した他の質問を見つけました。)
- バイナリ互換性を有効にします(ライブラリを作成する場合)
- コンパイル時間を短縮します
- データを非表示にします
上記の「利点」を考慮すると、私の意見では、それらのどれもPIMPLを使用する特に説得力のある理由ではありません。したがって、私はそれを使用したことがなく、PIMPLの有用性とそれを実際に使用して達成できることを破棄したため、結果としてプログラムの設計に支障をきたしました。
説明するためにそれぞれにコメントさせてください:
1.1。
バイナリの互換性は、ライブラリを作成する場合にのみ関係します。最終的な実行可能プログラムをコンパイルしている場合、他の誰か(バイナリ)ライブラリを使用していない限り、これは関係ありません。(つまり、元のソースコードがありません。)
これは、この利点の範囲と有用性が限られていることを意味します。これは、プロプライエタリ形式で出荷されるライブラリを作成する人だけが関心を持っています。
2.2。
コンパイル時間が非常に重要なプロジェクトで作業することがめったにない現代では、これが関連性があると個人的には考えていません。多分これはGoogleChromeの開発者にとって重要です。おそらく開発時間を大幅に増加させる関連する不利な点は、おそらくこの利点を相殺する以上のものです。私はこれについて間違っているかもしれませんが、特に最近のコンパイラとコンピュータの速度を考えると、それはありそうもないと思います。
3.3。
PIMPLがここにもたらす利点はすぐにはわかりません。ヘッダーファイルとバイナリオブジェクトファイルを出荷しても、同じ結果が得られます。私の目の前に具体的な例がなければ、PIMPLがここで関連している理由を理解することは困難です。関連する「もの」は、元のソースコードではなく、バイナリオブジェクトファイルを出荷することです。
PIMPLが実際に行うこと:
あなたは私の少し手を振る答えを許さなければならないでしょう。私はソフトウェア設計のこの特定の分野の完全な専門家ではありませんが、少なくともそれについて何かをお話しすることができます。この情報は、ほとんどの場合、デザインパターンから繰り返されます。著者はそれを「ブリッジパターン」、別名ハンドル、別名ボディと呼んでいます。
この本では、ウィンドウマネージャを作成する例を示します。ここで重要な点は、ウィンドウマネージャーがさまざまな種類のウィンドウとさまざまな種類のプラットフォームを実装できることです。
たとえば、
- 窓
- アイコンウィンドウ
- 3Dアクセラレーションを備えたフルスクリーンウィンドウ
- 他のいくつかの派手なウィンドウ
- これらはレンダリングできるウィンドウの種類です
と同様
- MicrosoftWindowsの実装
- OSXプラットフォームの実装
- LinuxXウィンドウマネージャー
- Linux Wayland
- これらはさまざまなタイプのレンダリングエンジンであり、OS呼び出しが異なり、機能も根本的に異なる可能性があります。
上記のリストは、別のユーザーがDVDプレーヤーなどのさまざまな種類のハードウェアで動作するソフトウェアの作成について説明した別の回答に記載されているリストと類似しています。(例が何であったかを正確に忘れています。)
ここでは、デザインパターンの本に書かれているものとは少し異なる例を示します。
重要なのは、継承階層を使用して実装する必要があるのは2つの異なるタイプですが、ここでは単一の継承階層を使用するだけでは不十分です。(N * Mの問題、複雑さは各箇条書きリストの数の2乗のようにスケーリングしますが、これは開発者が実装するのは現実的ではありません。)
したがって、PIMPLを使用すると、ウィンドウのタイプを分離し、実装クラスのインスタンスへのポインターを提供します。
だからPIMPL:
- N*M問題を解決します
- 継承を使用してモデル化されている2つの根本的に異なるものを切り離し、1つのモノリスではなく、2つ以上の階層が存在するようにします。
- 正確な実装動作の実行時交換を許可します(ポインターを変更することにより)。これは状況によっては有利な場合がありますが、単一のモノリスは実行時の動作の選択ではなく静的(コンパイル時)の動作の選択を強制します
これを実装する方法は他にもあるかもしれませんが、たとえば多重継承を使用する場合などですが、少なくとも私の経験では、これは通常、より複雑で難しいアプローチです。