组合而不是继承,单一职责

今天在写C++程序的时候,有一个使用了三年多的模型,大概是这样的:

有一个界面捕获需要主窗口的鼠标事件的时候,那么他就需要从IMouseEvent继承接口,然后像RegisterEvent(IMouseEvent *event)注册,如果有鼠标事件,主窗口会通过调用虚函数来通知这个界面
 
我们一般的代码是这样的:
class MyUI:public IMouseEvent
{
    virtual void OnMouseEvent( MouseEvent &event );
    
    virtual void OnMouseLeftDown( MouseEvent &event);
 
    virtual void OnMouseRightDown(MouseEvent &evnet)
 
    Other UI Process Function
    ......
}
 
MyUI *ui = new MyUI();
MainUI->RegisterEvent( ui );
 
这样有两个坏处:
1.把事件处理机制混合在窗口里面了,随着代码的增加,鼠标模式的处理会更加复杂,这点在现在的维护上已经体现出来了
2.MyUI不得不依赖IMouseEvent接口
 
想起来上次面试的时候,对方问我设计模式的问题,我一直不是很注重设计模式,可能跟我的工作有关,我更多的是在处理逻辑而不是设计,所以那次回来后我一直在想,我们的代码写得越久越难维护是不是跟我不注重设计模式有关,设计模式有一个单一原则,能否把鼠标处理事件移动出去,这样就变成
 
class MyUIMouseEvent:public IMouseEvent
{
    MyUIMouseEvent(MyUI *UI);
 
    virtual void OnMouseEvent( MouseEvent &event );
    
    virtual void OnMouseLeftDown( MouseEvent &event);
 
    virtual void OnMouseRightDown(MouseEvent &evnet)
 
    ......
}
 
然后利用组合
class MyUI
{
public:
    MyUIMouseEvent *m_MouseEvent;
 
    friend class MyUIMouseEvent;
}
这样的话,鼠标事件对界面所进行的逻辑处理会在MyUIMouseEvent里面处理,看起来起码比以前更清爽多了,也实现了单一职责(虽然我不知道这个是不是)
 
但是这样的话MyUIMouseEvent还是必须依赖于IMouseEvent,因为开发环境已经切换到vs2010了,开始支持bind和function系列函数了,通过这两个函数,我们可以利用function和bind取代虚函数,而且减少头文件依赖
比如在.h里面
class MyUIMouseEvent
{
    MyUIMouseEvent(MyUI *UI);
 
    void OnMouseEvent( MouseEvent &event );
    
    void OnMouseLeftDown( MouseEvent &event);
 
    void OnMouseRightDown(MouseEvent &evnet)
}
 
MyUIMouseEvent的头文件不会产生任何的依赖,而是在cpp里面通过bind和function绑定,然后提供新的RegisterEvent接口专门注册这一些列函数,三个头文件没有产生任何的依赖,比之前好多了
 
因为程序已经变得很大了,经常改动一个头文件的东西,一大堆的文件都要重新编译,所以最近越来越注意如何减少头文件依赖





posted @   linyilong  阅读(362)  评论(0编辑  收藏  举报
编辑推荐:
· 如何编写易于单元测试的代码
· 10年+ .NET Coder 心语,封装的思维:从隐藏、稳定开始理解其本质意义
· .NET Core 中如何实现缓存的预热?
· 从 HTTP 原因短语缺失研究 HTTP/2 和 HTTP/3 的设计差异
· AI与.NET技术实操系列:向量存储与相似性搜索在 .NET 中的实现
阅读排行:
· 周边上新:园子的第一款马克杯温暖上架
· Open-Sora 2.0 重磅开源!
· .NET周刊【3月第1期 2025-03-02】
· 分享 3 个 .NET 开源的文件压缩处理库,助力快速实现文件压缩解压功能!
· [AI/GPT/综述] AI Agent的设计模式综述
点击右上角即可分享
微信分享提示