2012-09-29 31 views
1

我正在为状态机表示编写一个图编辑器应用程序。我有两个交互工具在画布和图表上运行。第一个称为“编辑工具”,负责创建新的图元素,如节点和边。第二个被称为“移动工具”并作用于图表布局,id est,它移动节点并更新边缘。这是简单的解释,但我不需要给你更多的细节来问我的问题。如何实现专门的事件处理程序?

我想知道什么是处理事件,并将其在整个工具分配最有效的和有组织的方式

我知道我可以简单地拦截在他们的呼叫事件,并根据一些处理选定的工具,当前状态和目标对象,但这种方式代码扩展到一个巨大的if (...) else if (...)块,上下文标志等;并变得极难维护。

这种情况下是否有任何常见的代码模式?你能举一些例子吗?我可以查看哪些开源项目以了解更多信息?

回答

1

我不能完全肯定,如果我收到了你的问题的权利。从阅读这个问题看来,你正在寻找观察者的设计模式。然而,你给自己的问题的答案并不符合这种解释......

如果你想要你的UI在每次状态机改变时都会更新,那么你可能需要看一下Wikipedia,CodeProject处的观察者模式,或者只是谷歌。它是最常见的设计模式之一,如果你不知道它,你肯定应该花几分钟的时间来亲身体验它。

作为一个示例,说明如何将此模式应用于您的域,让我们假设您的LayoutManager在用户使用编辑工具添加或移除节点/边缘时重绘图。您不想直接从编辑工具中调用LayoutManager,因为这会强烈地影响这两个组件。因此,你可以按如下方式指定一个观察者接口(我使用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订阅状态机模型,每一次模型的变化(在这里被添加一个节点),将自动通知。您可以为不同的通知设置不同的观察者界面,或者您可以为单个观察者界面提供不同类型的通知的独立功能。

相关问题