天天看點

把需求變化帶來的代碼修改成本降至最低的一種方法

為解決工作中一些繁瑣的問題, 寫了一個GUI程式, 操作界面是這個樣子的

把需求變化帶來的代碼修改成本降至最低的一種方法

這個程式的實作起來并不是非常的繁瑣, 但在界面的互動操作上, 也不僅僅隻是展示資料。 如上面圖檔所見,清單中的每一條記錄每一個資料項都需要可以填寫和選擇; 需要添加和删除記錄;還需要調整記錄的位置;向上移動、向下移動;要實作這些操作, 控制UI的程式其實挺複雜的。

我哼哧哼哧的把這個程式寫完, 拿去給同僚們示範使用方法, 同僚們給我提出了不少的建議。 其中的一條是:把界面分割成上下兩部份的方式替代清單中類型字段的選擇, 以簡化互動操作, 也就是說簡化過後, 程式的操作界面要變成下面這個樣子

把需求變化帶來的代碼修改成本降至最低的一種方法

以寫代碼為生的同學肯定知道, 需求更改後的實作并不是一件愉快的事, 雖然給我提建議的同僚并不是需求方, 但是他們的一些意見我不得不考慮, 我也不得不承認, 在軟體操作的便利性上, 同僚們給出的意見确實要比原來強上不少。 但是假如真的要以這種方式去修改程式, 大家可以設身處地的想想, 假如這個程式是由你開發的, 要做這樣的修改, 會不會是一件很費勁的事情? 大量的代碼邏輯變動或者以複制代碼的方式讓界面上的兩個清單的UI互動操作互不沖突并且不影響結果的正确性是不可避免的,甚至于在極端情況下, 會讓整個程式的結構産生變動也未可知。 當同僚們建議的聲音鑽入我的耳朵的第一瞬間, 我就覺得這是一件不可能實作的事情, 第一反應就是立馬反駁, 并表示這是一項無法完成的工作。

事後,我靜下心來思考這個事情。 首先, 同僚們的建議是完全合理的, 除了程式的修改難度問題,我找不到合适的理由拒絕; 其次, 我回憶我寫這個程式時代碼邏輯的組織方式,我發現假如我要把程式修改的符合像同僚們建議的那樣似乎也并不需要費多少功夫, 而且可以說是非常非常的簡單, 簡單到不可思議。 我照着我腦海中生成的方案去做, 隻花了15分鐘左右時間就完成了任務, 實作了指定的效果, 而且隻修改了五六行核心業務邏輯代碼, 界面和操作的變動與工作量以及代碼的修改完全不成正比,這讓我自己也覺得很驚。 修改的過程中我大緻做了下面這些事情

界面部份的改動

1.      調整界面中各個元件的尺寸, 騰出一塊空白的區域來放第二個清單

2.      把第一個清單的xaml代碼複制一份到剛剛騰出來的位置, 這段xaml代碼是一個ListView控件,是以需要給它命一個新的名稱

3.      把界面右上角「添加一項」按扭也複制一份, 放在第二個ListView的上方位置, 并綁定一個新事件

程式部份的改動

  為新的ListView綁定一個資料源

把需求變化帶來的代碼修改成本降至最低的一種方法

2.  為新的「添加一項」綁定事件代碼

把需求變化帶來的代碼修改成本降至最低的一種方法

然後, 大功告成, 就這麼簡單的把這事給辦了

有同學可以會提出疑問:“不說别的, 就說第二個清單的删除、上移、下移這三項功能的事件代碼寫在哪了? 你這是當我們是沒寫過代碼的小白來忽悠嗎?”, 事實上, 這些代碼是有的, 都是複用前一個清單的事件代碼。“但為什麼針對前一個清單的事件代碼毫無變化的過渡到新的ListView上使用呢?這不符合正常程式設計邏輯”,這其實跟我程式代碼的設計方式有關

大家看到程式的界面中有許多界面互動操作的功能,如添加、删除、上移、上移, 隻要滑鼠點選在這些按扭之上, 界面就會立刻發生變化, 這勢必需要通過程式去控制界面元素。 這個程式是用C#和XAML開發了, 但考慮到閱聽人問題, 我用JavaScript和html舉個例子, 假如我們需要移除一個表格中的一項, 那麼我們肯定要通過文檔對象模型去操控這張html表格,比如說通過這樣的方式去移除

var ele = document.getElementById("表格行ID");

ele.parentNode.removeChild(ele);

為清單添加一也是同樣的道理, 上移下移清單項也是一樣, 隻是實作起來更加的困難複雜, 但這都是正常的實作思路。

然而,我卻不是以這種方式去實作這個WPF GUI程式的。 再舉個例子, 在我們開發Web應用程式時以清單的方式展示資料最常見不過,當我們要删除某一條資料時, 不使用ajax進行無重新整理删除的做法是,先删除資料,再重新整理頁面,那條需要删除的資料就被去除掉了, 資料庫和界面, 雙重的。 這種方法的優點就是邏輯簡單, 以重新整理頁面替代JavaScript操作DOM來進行界面更新; 缺點就是體驗差,沒有辦法做到無重新整理更新頁面。 對頁面的其它操作也可以相同的方式更新UI, 将記錄插入資料庫後重新整理頁面,界面上顯示的資料也會随之增加;修改資料庫中記錄的排序号碼,重新整理頁面後界上對應的資料項也會轉移到相應的位置;

我正是借用了這種浏覽器/伺服器架構的程式設計思路,才把問題簡單化,省略了各種動态更新UI的程式操作, 對UI的更新隻在ListView綁定資料的時候進行了。 我設計這個的核心思路大緻如下

1.  建立一個清單資料結構, 用來存放顯示在ListView控件中的内容

2.  執行添加操作時往這個清單結構中插入一條資料, 然後重新把資料綁定至ListView, 使其重新渲染界面。 所有添加操作都是以這種方式執行, 先更新資料結構, 再渲染ListView

3.  删除操作與添加操作相似, 先将資料項從清單資料結構中删除, 再讓ListView根據資料源重繪UI

4.  其它對UI的操作亦都是如此

将所有原本需要對UI進行的操作都轉移至對資料進行操作, 再根據被操作後的資料結果重繪UI, 這樣做的好處是代碼的邏輯變的清晰簡單了,除了将資料映射成界面的時候需要關注UI相關的邏輯, 其它時候隻關心資料就可以了, 操縱資料結構的難度顯然是低于操作界面元素的。缺點就是每一次互動操作導緻資料産生變化後, 都需要完全重繪UI,影響使用者體驗。對于Web應用程式這種影響很明顯,因為需要執行一次http請求,在浏覽器内重新整理頁面。 而對于windows GUI應用程式,這種體驗上的差距用肉眼幾乎難以觀察的到, 資料是從記憶體中讀取的, 沒有任何網絡開銷;而重繪界面的時間隻需要幾毫秒甚至更少,是以完全沒有理由去關注這些根本不會影響到軟體使用的問題, 我們應該關注的是如何簡化代碼,如何提升軟體可用性等實質性的問題。

我的程式以這種設計思路實作, 在應用同僚們提升出建議修改程式時,概括來說我就做了兩件事

1.  修改界面, 多加了一個ListView控件, 兩個控件的結構完全一樣

2.  把原來的一大份資料,拆成了兩份,分别綁定至兩個ListView

把需求變化帶來的代碼修改成本降至最低的一種方法

修改成

把需求變化帶來的代碼修改成本降至最低的一種方法

就這麼任性的搞定了

很多時候我們總是抱怨需求的變化導緻我們工作量加大, 每當聽到需求有變化需要把程式大改特改的消息時就像聽到了自己的女朋友跟别的男人跑了一樣激動, 認為一切都需要推倒重來, 所有的努力的付出都浪費了。 然而, 事實上, 代碼邏輯組織的有足夠的技巧, 完全可以将需求變化帶來的對代碼改動的影響降至最低。每一個專業的程式員都應該具備“應對變化”的能力。我們的時間是有限且寶貴的, 寫出愚蠢的需要花大量時間去維護以及無法應對變化的代碼是一種浪費時間、浪費生命的慢性自殺,是以,寫代碼時注意技巧,永遠不會錯

本文轉自 sshpp 51CTO部落格,原文連結:http://blog.51cto.com/12902932/1928057,如需轉載請自行聯系原作者