Visualization Tool Kit(VTK)など

CDocument派生クラスがデータおよびそのシリアライズを提供し,データの表示をViewが担当するのがDoc-Viewアーキテクチャである.
このパターン自体には問題がないがMFCが提供するDoc-Viewアーキテクチャにはいささか問題がある.

機能

基本となる機能は下記の通りである.
  • CView派生クラスはGetDocumentでCDocument派生クラスを取得でき,データにアクセスできる.
  • CDocument派生クラスはUpdateAllViewsで表示の更新を全てのCView派生クラスに通知できる.

問題点

  • 非CView派生クラスからCDocument派生クラスに直接アクセスができない.
  • CDocument::UpdateAllViewsの通知はCView派生クラスにしか届かない.

代替手法

  • ウィザードでDoc-Viewアーキテクチャのサポートのチェックを外す.
  • CWinApp派生クラスにCDocumentの代替となる独自のデータクラスを加える.
  • CWinApp派生クラスにGetDataなどのデータクラスへのアクセス関数を追加する.
  • CWinAppクラスのポインタはグローバル関数GetAfxAppで取得できる.これを実際のCWinApp派生クラスにダウンキャストすればよい.
  • データからGUIへの通知にはBoost.Signals2などの汎用的なデリゲータライブラリを用いれば良い.
  • その理由はデータクラスはビュークラスに依存すべきでないからである.さもなければ全てのビュークラスのヘッダーファイルをインクルードしその参照を手に入れる必要がある.

Boost.Signal2による実装例

リファレンスのExample: Doc-Viewと対してかわりないので公開しておく.
  • コンストラクタでModelBase派生クラス(CDocumen派生クラスの代替)をViewBase派生クラス(おそらくCWnd派生クラスと多重継承する)に渡す.
  • ModelBase派生クラスはCWinApp派生クラスのメンバーにし,InitInstanceあたりで初期化する.
  • 本手法では,新しいビュークラスを追加した場合でも必要なデータを手に入れることができるならば,ModelBase派生クラスを変更する必要がない.
この例ではUpdateAllViewsの代わりにmSignal()を呼べば,全てのSlot(View)に通知される.
class ModelBase
{
public:
  boost::signals2::connection Connect(const signal_t::slot_type &subscriber)
  {
    return mSignal.connect(subscriber);
  }
protected:
  boost::signals2::signal<void ()>  mSignal;
};

class ViewBase
{
public:
  ViewBase(ModelBase& model) : mModel(model) { mConnection = mModel.Connect(boost::bind(&ViewBase::Update, this));}
  void Update() { UpdateInternal(); }
protected:
  virtual void UpdateInternal() = 0;
private:
  boost::signals2::connection  mConnection;
  ModelBase& mModel;
};

コメントをかく


「http://」を含む投稿は禁止されています。

利用規約をご確認のうえご記入下さい

Menu

メニュー

チュートリアル

アルゴリズム(数学)

並列計算

STL

#include<memory> #include<string> #include<sstream> #include<algorithm> #include<functional> #include<numeric>

Media Foundation

【メニュー編集】
Wiki記法ガイド

メンバーのみ編集できます