在經歷過上一篇的慘不忍睹程式碼之後,就開始思考:為什麼我用物件導向寫出來的程式會是這個樣子?為什麼我寫出來的東西,跟曾經看過的物件導向程式差這麼多?

幸好後來有一段蠻長的空檔,讓我有充裕的時間思考反省這個問題,更慶幸的是也有足夠時間去改正缺失。經過反思之後,終於發現程式慘不忍睹的原因:當時寫程式的第一個反應,幾乎都是「現在要寫哪個步驟的程式」。換句話來說就是有一點見招拆招、打游擊的感覺。

接著就趁那段蠻長的空檔,不斷反覆琢磨、回味之前經常在學習的理論,也就是「術語定義篇」裡的內容,然後調整自己寫程式的思考模式,並開始按照這樣的心法,來思考如何實現我要的功能和效果。也就是往後在寫程式的時候,應該要這樣思考:現在要實現的功能,有哪幾個要做互動的事物?這些事物各別有哪些特徵和行為?最後直接來看改進之後的 code-behind 程式碼。

  1 using System;
  2 using System.Windows.Forms;
  3 
  4 
  5 namespace SybaseUtility
  6 {
  7     public partial class fTransmitter : Form
  8     {
  9         private Transmitter tt = new Transmitter();
 10         private TransmitterOperation to;
 11         private ITransmitting t;
 12 
 13         public fTransmitter()
 14         {
 15             InitializeComponent();
 16         }
 17 
 18         private void fTransmitter_Load(object sender, EventArgs e)
 19         {
 20             to = new TransmitterOperation(new Button[] { btnSendAll, btnSendPick, btnRestoreAll, btnRestorePick }, labKeyword, dgvPreview, tsslbStatus);
 21             to.CreateComboBoxItem(cbxGenre);
 22         }
 23 
 24         private void rbUnSend_CheckedChanged(object sender, EventArgs e)
 25         {
 26             tt.PreviewState = PreviewState.UnSend;
 27             to.ButtonStateForUnSend();
 28         }
 29 
 30         private void rbSended_CheckedChanged(object sender, EventArgs e)
 31         {
 32             tt.PreviewState = PreviewState.Sended;
 33             to.ButtonStateForSended();
 34         }
 35 
 36         private void cbxGenre_SelectedIndexChanged(object sender, EventArgs e)
 37         {
 38             tt.Genre = cbxGenre.SelectedItem.ToString();
 39 
 40             switch (tt.Genre)
 41             {
 42                 case "客户资料":
 43                     t = new CustomersTransmitting();
 44                     break;
 45 
 46                 case "销售单":
 47                     t = new SaleListsTransmitting();
 48                     break;
 49 
 50                 case "维修历史":
 51                     t = new RepairingTransmitting();
 52                     break;
 53 
 54                 case "会员卡资料":
 55                     t = new VIPCardsTransmitting();
 56                     break;
 57 
 58                 case "积分兑换项目":
 59                     t = new CreditConvertItemsTransmitting();
 60                     break;
 61 
 62             }
 63 
 64             to.ShowFilterText(t);
 65         }
 66 
 67         private void btnPreview_Click(object sender, EventArgs e)
 68         {
 69             Validating v = new Validating(cbxGenre, rbUnSend, rbSended);
 70             v.Validate();
 71 
 72             if (string.IsNullOrEmpty(v.errorMsgText))
 73             {
 74                 to.Preview(t, tt);
 75             }
 76         }
 77 
 78         private void tbKeyword_TextChanged(object sender, EventArgs e)
 79         {
 80             Validating v = new Validating(cbxGenre, rbUnSend, rbSended);
 81             v.Validate();
 82 
 83             if (string.IsNullOrEmpty(v.errorMsgText))
 84             {
 85                 to.Filtering(t, tt, tbKeyword.Text);
 86             }
 87         }
 88 
 89         private void btnSendAll_Click(object sender, EventArgs e)
 90         {
 91             tt.FinishState = FinishState.Updated;
 92             if (t != null) to.SendAll(t, tt);
 93         }
 94 
 95         private void btnSendPick_Click(object sender, EventArgs e)
 96         {
 97             tt.FinishState = FinishState.Updated;
 98 
 99             if (t != null) to.SendPick(t, tt);
100         }
101 
102         private void btnRestoreAll_Click(object sender, EventArgs e)
103         {
104             tt.FinishState = FinishState.Restored;
105             if (t != null) to.RestoreAll(t, tt);
106         }
107 
108         private void btnRestorePick_Click(object sender, EventArgs e)
109         {
110             tt.FinishState = FinishState.Restored;
111             if (t != null) to.RestorePick(t, tt);
112         }
113     }
114 }

很明顯的,慘不忍睹的版本,總共 689 行程式碼,而且是個大雜燴,經常害我寫程式寫到忘了自己是誰;重構之後的程式碼只有 114 行,而且層次清析,哪一段程式在做什麼都簡單明瞭。雖然這個版本的程式已經有很大的改進,但還是有個缺點,就是仍看得到 switch case 的程式片段,這在日後遇到需求變更時,一定得再回來改寫程式,這樣也不是很好的開發體驗。

我要的最終效果,是「不因需求變更而改動用戶端程式碼」,當然這個部份屬於下個階段的重構,因為會牽涉到設計模式,這又是比物件導向更抽象的東西,日後再發文分享心得。

posted on 2015-11-04 14:44  吉格艾諾  阅读(161)  评论(0编辑  收藏  举报