swich....case 條件分支多了之後,會嚴重的破壞程式的美觀性。
比如這個
上述代碼是用於兩個進程之間通訊的代碼,由於通訊的枚舉特別的多,所以case的分支特別的多。導致了代碼的可讀性,可維護性嚴重下降。經過尋找資料和重構,想到了一種可行的在這種情況替代switch...case的方案——————利用索引值對。
聲明索引值對對象
針對進程通訊的代碼邏輯,構建了如下的索引值對。
Dictionary<EnumMsg, Action<Message>> mMessageReceiver = new Dictionary<EnumMsg, Action<Message>>();
這個索引值對的鍵是自訂的訊息枚舉,值是Action<Message>
的委託。這樣訊息枚舉和訊息枚舉對應的處理函數就一一對應了。
初始化時註冊訊息
在初始化時,將枚舉與相應的Action進行裝載。
private void SubscribeMessageReceiver(){ mMessageReceiver.Add(EnumMsg.SEND_PANO_PARAM, UpdatePano); mMessageReceiver.Add(EnumMsg.CMD_PANO_VIEW, ExecutePanoViewCommand); mMessageReceiver.Add(EnumMsg.CMD_PANO_LENGTH_MEASURE, ExecuteLengthMeasure); mMessageReceiver.Add(EnumMsg.CMD_PANO_AREA_MEASURE, ExecuteAreaMeasure); mMessageReceiver.Add(EnumMsg.CMD_PANO_QUICK_PICK, ExecuteQickPickCommand);}
這樣就把索引值對對象構建完成。那麼就可以將重構swith...case程式碼片段了。
修改switch...case程式碼片段
重構前的switch....case代碼
protected override void DefWndProc(ref Message m) { switch (m.Msg) { case ((int)API.WM_COPYDATA): { switch ((int)m.WParam) { case ((int)Procedure.OpenSkyline): m = OpenSkylineView(m); break; case ((int)Procedure.Measureare): m = Measure(m); break; case ((int)Procedure.Measurelength): m = Measure(m); break; } } break; default: break; } base.DefWndProc(ref m); }
基於索引值對來尋找對應的處理方法的代碼
protected override void DefWndProc(ref Message m) { base.DefWndProc(ref m); if (m.Msg == (int)API.WM_COPYDATA) { EnumPanoMsg pEnumPanoMsg = (EnumPanoMsg)m.WParam; if (mMessageReceiver.Keys.Contains(pEnumPanoMsg)) { mMessageReceiver[pEnumPanoMsg](m); } } }
根據索引值對的鍵來進行尋找,當需要增加新的case分支的時候,原本的方法需要更改switch....case分支,但是利用索引值對的方法,只需要編寫新的處理方法,並且在索引值對中增加新的一對索引值就可以了。代碼簡潔美觀,沒有一長串令人厭煩的case了。