0

MFC では、提供される特定のメカニズムにより、プログラマーは、オブジェクト指向フレームワークの最も望ましい機能であるモジュール性、カプセル化、および情報の隠蔽を回避できます。

(多くの) 例の 1 つが Owner Drawn コントロールです。子コントロールのサブクラスで実装DrawItemし、そのサブクラスでそのコントロールのすべての描画を行うことを選択して、よりモジュール的に見えるようにすることができます。

class CustomButton: CButton{
     // --- Lots of stuff, DECLARE_DYNAMIC etc

     virtual void DrawItem(LPDRAWITEMSTRUCT lpdis){
          // Drawing code for this button in the button's subclass
     }
};

WM_DRAWITEM...または、OnDrawItem を介して親 Window クラスでメッセージを処理することを選択できます

class MainFrame: CFrameWnd{
     // --- Lots of stuff, DECLARE_DYNAMIC etc

     CustomButton button; 

     afx_msg void OnDrawItem(LPDRAWITEMSTRUCT lpdis, UINT id){

          if(id == CUSTOM_BUTTON_ID){     
               // Drawing code for this button in the button's subclass
          }
     }
};

後者の状況では、コントロールの描画はコントロール サブクラスの外にあります。つまり、「OOP データ構造は独自の演算子を持ち歩く傾向がある」という概念が損なわれます..そうですか?

だから私の質問は次のとおりです。どれが「ベストプラクティス」と見なされますか? 2 番目の理由が存在するのには理由があるはずです。

4

2 に答える 2

1

この質問は、メッセージを子に渡すだけでなく、代わりに子に処理させるのではなく、子を対象としたメッセージを処理するために、1つ以上の子オブジェクトを含む親オブジェクトを持つことがいつ合理的であるかを尋ねているようです。

特定の例は、MFC ウィンドウ クラスで、他のウィンドウ オブジェクト (この場合はボタン) を含むウィンドウ オブジェクトが、メッセージを処理するために子に渡すだけでなく、描画メッセージを処理しています。

基本的な答えは、場合によるということです。ウィンドウ オブジェクトを構成していて、その一部として、子コントロールの外観を変更するために、子コントロールの描画動作をオーバーライドしている場合があります。たとえば、親ウィンドウの情報に基づいて外観を変更したい一連のボタンがある場合、外観を変更するために子コントロールの描画を上書きしたい場合があります。

これは、親ウィンドウが子コントロールに描画オブジェクトを提供できるようにすることで、複数の異なるタイプの外観を可能にするボタン オブジェクトを持つことに似ています。その結果、子はデフォルトの描画動作を持ち、親は描画オブジェクトを提供することでオーバーライドします。

この種のプログラミングの問題に関する簡単な説明を提供する、戦略パターンに関するウィキペディアのこの記事または他のパターンへのサイド リンクを含む戦略パターンに関するこの記事を参照してください。もう 1 つの例は、一連の責任パターンです。

この特定の例では、親が使用する描画記述オブジェクトを子に提供するのではなく、親は描画メッセージをインターセプトし、描画自体を行っています。

子コントロールの他の機能に影響を与えずに子コントロールの外観を変更できる場合、これは悪いアプローチではありませんが、メンテナンスやその他の変更を行っているプログラマーを混乱させる可能性があります。ただし、この種のオーバーライディング動作は、ウィンドウ領域の外側にあるコンポーネントのどの部分も描画されないように、一部のウィンドウ コンポーネントの描画がクリップされるウィンドウ クリッピングなどの他のインスタンスで見られることがあります。

したがって、親オブジェクトが親の子オブジェクトをターゲットとするメッセージをインターセプトして処理するというアプローチは、親が達成したいことに応じて、さまざまな親が子の特定の動作を変更できるようにする上で、非常に高い柔軟性を提供します。

ただし、この柔軟性には代償があります。

于 2012-10-29T18:11:48.087 に答える
-1

2 番目の状況で、CUSTOM_BUTTON_ID がコントロールによって内部的に使用されるデータである場合、最適でない OOP になります。これは、David Parnas (http://www.cs.umd.edu/class/spring2003/cmsc838p/Design/criteria.pdf) によって定義された情報隠蔽の概念に違反します。内部情報が変更された場合、親ウィンドウは変更の影響を受けるため、一致するようにそれ自体を変更する必要があります。これが、情報の隠蔽がモジュール性を促進する方法です。データを必要なものにバンドルして保持します (そして、必要のないものからは隠します)。

コメントに基づくと、これは悪い例です。なぜなら、CUSTOM_BUTTON_ID は実際にはコントロールではなく親ウィンドウに含まれて使用されるデータであるため、情報隠蔽の違反がないからです。コントロールの描画は、引き続きコントロール内で行われます。親ウィンドウは、コントロールの Draw メソッドを呼び出すだけです。

于 2012-10-26T19:28:22.483 に答える