refactor : switch-case

来源:互联网 发布:isis 剿灭 知乎 编辑:程序博客网 时间:2024/04/28 04:40

前几天维护了一段代码, 是个超过2000行的switch, 不到100个自定义消息, 变量有在消息处理函数入口处定义的, 有在case处理中定义的.

有点晕了...

后来和同事商量了一下, 采用如下规则, 进行了重构, 花了一个下午的时间搞定.


规则:

  * switch中的case处理,如果需要临时变量来处理, 即使只有2,3行代码, 也要封进case处理子函数.

  * 如果该case的处理,不需要定义临时变量,但是行数超过5行(e.g. 调用了5个方法),  也要封进case处理子函数.

  * 如果有可能, 每一个case处理都要封进case子函数.(e.g. 我们是从头添加的代码, 或者来不及重构, 在没有重构的switch-case中增加新的case处理)

  * case子函数封装定义 类似于 :

 

BOOL CSomeClass::WndMessageProc_case_x(UINT uMsg, WPARAM wParam, LPARAM lParam, LRESULT& lRc)


重构后的switch-case样例:

#define WM_MSG_BASE     WM_USER + 1000#define WM_OurMsg_after_process_need_return            WM_MSG_BASE + 1#define WM_OurMsg_after_process_need_not_return        WM_MSG_BASE + 2#define WM_OurMsg_3                                    WM_MSG_BASE + 3#define WM_OurMsg_N                                    WM_MSG_BASE + NLRESULT CMainDlg::WndMessageProc(UINT uMsg, WPARAM wParam, LPARAM lParam){    /// 这个消息处理只允许定义下面的1个变量, 用于带参数的case处理子函数    /// e.g.  BOOL CMainDlg::WndMessageProc_case_x(UINT uMsg, WPARAM wParam, LPARAM lParam, LRESULT& lRc)    LRESULT         lRc = 0;    /// 是否不处理我们所有的自定义消息?     /// e.g. 程序进入了退出程序的处理 or 有些自定义消息在某种情况下不用处理    if (WndMessageProc_not_process_OUR_ALL_MSG(uMsg, wParam, lParam, lRc))    {        /// 这个消息是我们的自定义消息, 且不用处理, 直接返回了        return S_OK;    }    /// 如果自定义消息或者系统消息被处理了, 直接返回, 不走基类的消息处理    /// 如果自己处理了系统消息,又想让基类继续处理, 请不要返回    switch (uMsg)    {    case WM_OurMsg_after_process_need_return:        {            /// 如果不需要定义临时变量, 且调用的方法不超过5行, 可以直接写在这            if (fn_process_case_1())                fn_process_case_2();            else                fn_process_case_3();            return S_OK;        }        break;    case WM_OurMsg_after_process_need_return:        {            /// 如果不需要定义临时变量, 且调用的方法不超过5行, 可以直接写在这            if (fn_process_case_1())                return S_OK;            fn_process_case_2();            fn_process_case_3();            /// 继续执行基类的消息处理        }        break;        /// other case ...    /// 如果是从头开始写switch case, 觉得还是都封装成 WndMessageProc_case_x 好些    /// BOOL CMainDlg::WndMessageProc_case_x(UINT uMsg, WPARAM wParam, LPARAM lParam, LRESULT& lRc)    case WM_LBUTTONDOWN:        {            if (WndMessageProc_case_1(uMsg, wParam, lParam, lRc))                return lRc;        }        break;    case WM_CLOSE:        {            if (WndMessageProc_case_2(uMsg, wParam, lParam, lRc))                return lRc;        }        break;    default:        break;    }    return __super::WndMessageProc(uMsg, wParam, lParam);}

case处理子函数的模拟:

BOOL CMainDlg::fn_process_case_1() {return FALSE;}void CMainDlg::fn_process_case_2() {return; /** bala bala bala then return */}void CMainDlg::fn_process_case_3() {return; /** bala bala bala then return */}BOOL CMainDlg::WndMessageProc_case_1(UINT uMsg, WPARAM wParam, LPARAM lParam, LRESULT& lRc){    /** bala bala */    lRc = S_OK;    return TRUE; ///< 我已经处理了, 不需要别人再处理, 返回lRc}BOOL CMainDlg::WndMessageProc_case_2(UINT uMsg, WPARAM wParam, LPARAM lParam, LRESULT& lRc){    /** bala bala */    lRc = S_OK; ///<     return FALSE; ///< 我没有处理, 需要别人再处理, 不用理会lRc}



0 0