您好,登錄后才能下訂單哦!
為解決工作中一些繁瑣的問題, 寫了一個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
修改成
就這么任性的搞定了
很多時候我們總是抱怨需求的變化導致我們工作量加大, 每當聽到需求有變化需要把程序大改特改的消息時就像聽到了自己的女朋友跟別的男人跑了一樣激動, 認為一切都需要推倒重來, 所有的努力的付出都浪費了。 然而, 事實上, 代碼邏輯組織的有足夠的技巧, 完全可以將需求變化帶來的對代碼改動的影響降至最低。每一個專業的程序員都應該具備“應對變化”的能力。我們的時間是有限且寶貴的, 寫出愚蠢的需要花大量時間去維護以及無法應對變化的代碼是一種浪費時間、浪費生命的慢性自殺,所以,寫代碼時注意技巧,永遠不會錯
免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。