关于MFC监听器的相关了解
最近有个项目,所搭框架为了减少耦合,希望MainFrame中View不依赖于Mainframe,即MainFrame中含有view类而view中不会包含MainFrame的相关信息。
现在遇到一个问题,比如无论如何我们也会需要View在处理自己的相关内容时需要将一些信息告诉MainFrame,而我们又不希望View包含MainFrame的头信息,为了不导致两个文件的耦合,采用一种监听器的机制来实现该操作。
其想法是在View类中建立一个接口,使得View包含该接口指针的成员的变量;同时在MainFrame中将该接口进行实现,即创建由此接口派生出来的子类,将该子类的指针加到View中,这样在View进行先关操作时,可以发送一个消息给MainFrame的同时,又不会包含MainFrame的头文件,即达到了消息响应的功能,也不会导致两个不同层级类之间的耦合。具体实现如下:
在View类中,增加如下代码:
1 Class CMyView: public CView: 2 { 3 public: 4 // 创建接口 5 struct IListener 6 { 7 virtual void OnChange() = 0; 8 } 9 10 // MainFrame可以通过该函数在View中增加监听器的实例,以智能指针实现 11 void AddListener(std::shared_ptr<IListener> listener) 12 { 13 _listener = listener; 14 } 15 16 private: 17 std::shared_ptr<IListener> _listener; 18 // 对监听器发出消息 19 void NotifyChange() 20 { 21 if(_listener) 22 { 23 _listener->OnChange(); 24 } 25 } 26 }
在MainFrame中增加代码:
1 // 可以直接加在.cpp文件中 2 class CListenerForMyiView : public CMyView::IListener 3 { 4 public: 5 CListenerForMyView(CMainFrame& frame): _frame(frame) {} 6 virtual void OnChange() 7 { 8 _frame.OnChange(); 9 } 10 11 CMainFrame& _frame; 12 }; 13 14 void CMainFrame::OnChange() 15 { 16 //具体实现 17 } 18 19 void CMainFrame::AddListenerForView() 20 { 21 auto view = GetMyView(); 22 ASSERT(view != nullptr); 23 //创建一个已存在view的监听器(这里目前只考虑只有一个view) 24 std::shared_ptr<CLintenerForMyView> listener(new CListenerForMyView(*this)); 25 //调用View中的函数,确保正确加入监听器的实例 26 view->AddListener(listener); 27 }
这样只需要在view创建之后,MainFrame调用AddListenerForView就可以创建一个可以监听的实例。