1

ステート マシン表現用のダイアグラム エディター アプリケーションを作成しています。キャンバスとダイアグラムで動作する 2 つの対話ツールがあります。最初のものは「編集ツール」と呼ばれ、ノードやエッジなどの新しいダイアグラム要素の作成を担当します。2 つ目は「移動ツール」と呼ばれ、ダイアグラム レイアウトに作用し、id est でノードを移動し、エッジを更新します。簡単な説明ですが、質問するのに詳細を説明する必要はありません。

イベントを処理してツール間で配布する最も効率的で組織的な方法を知りたい

呼び出し時にイベントをインターセプトし、選択したツール、現在の状態、およびターゲット オブジェクトに従って何らかの処理を行うことができることはわかっていますが、この方法では、コードは巨大なif (...) else if (...)ブロック、コンテキスト フラグなどに拡張されます。となり、維持が非常に困難になります。

この種の状況に共通するコード パターンはありますか? いくつか例を挙げていただけますか?詳細を知るために参照できるオープンソース プロジェクトは何ですか?

4

2 に答える 2

1

あなたの質問が正しかったかどうかは完全にはわかりません。質問を読むと、オブザーバーのデザイン パターンを探しているようです。しかし、あなた自身の質問に対するあなたの答えは、その解釈と実際には一致しません...

たとえば、ステート マシンが変更されるたびに UI を更新する場合は、WikipediaCodeProjectでオブザーバー パターンを調べたり、Google で検索したりできます。これは最も一般的な設計パターンの 1 つであり、知らない場合は、数分かけてよく理解してください。

このパターンをドメインに適用する方法の例として、ユーザーが編集ツールでノード/エッジを追加または削除するたびに、LayoutManager でダイアグラムを再描画するとします。編集ツール内から LayoutManager を直接呼び出すことは望ましくありません。これは、これら 2 つのコンポーネントが強く結び付けられるためです。したがって、オブザーバー インターフェイスを次のように指定できます (ここでは C++ を使用します。これは、アプリケーションがどの言語で記述されているかがわからないためです)。

class StateMachineModelObserver
{
public:
   virtual void nodeChanged(Node* n)=0;
   virtual void edgeChanged(Edge* e)=0;
};

ステート マシン モデルへの変更について通知を受けたいサブジェクトは、そのクラスから継承し、その機能を実装します。例えば:

class MyStateMachineLayoutManager : public StateMachineModelObserver
{
public:
   void foo() {} // these are 
   void bar() {} other functions of the layout manager

   virtual void nodeChanged(Node* n)
   {
      redraw();
   }

   virtual void edgeChanged(Edge* e)
   {
      redraw();
   }
};

ここで、ステート マシン モデルが通知へのサブスクライブとサブスクライブ解除を可能にする機能を提供する必要があり、通知を送信する必要があります。

class MyStateMachineModel
{
public:
   Node* addNode()
   {
      Node* n=new Node();
      insertNodeIntoModel();
      notify(n);
      return n;
   }

   void subscribe(StateMachineModelObserver* o)
   {
      m_mutex.lock();
      m_observers.insert(o);
      m_mutex.unlock();
   }

   void unsubscribe(StateMachineModelObserver* o)
   {
      m_mutex.lock();
      m_observers.insert(o);
      m_mutex.unlock();
   }

private:
   void notify(Node* n)
   {
      m_mutex.lock();
      for_each(m_observers.begin(), m_observers.end(),
         [](StateMachineModelObserver* o)
         {
            o->nodeChanged(n);
         }
      );
      m_mutex.unlock();
   }

   std::set<StateMachineModelObserver*> m_observers;
   std::mutex m_mutex;
};

あとは、LayoutManager をステート マシン モデルにサブスクライブするだけで、モデルが変更されるたびに (ここではノードが追加されます)、自動的に通知されます。さまざまな通知に対してさまざまなオブザーバー インターフェイスを使用することも、さまざまな種類の通知に対して個別の機能を備えた単一のオブザーバー インターフェイスを使用することもできます。

于 2012-09-30T17:22:31.627 に答える
0

ステートマシンで操作できるGUIの設計を説明する非常に優れた記事を見つけました:http://lassala.net/2008/02/05/state-machines-and-gui-interaction-part-i //

于 2012-09-29T21:37:19.843 に答える