從一名技術開發人員到實施人員的蛻變,從不同的角度看待同一個問題,或許會有不一樣的結果。這里記錄一下最近一個項目實施的案例,非常有感觸!
一. 項目情況簡介
本次項目是給一個國外生產型企業做倉庫方面的系統,其中有一個功能就是給倉庫做一個電子看板。所謂的電子看板就是在一個大屏幕上顯示倉庫進料和出料的情況,在大屏幕上顯示指定數量的單號信息,就和醫院的叫號系統一樣,每行數據不停的向上滾動。
上面這個功能其實非常簡單,就是查詢相應的數據在屏幕上顯示即可. 倉庫每天可能收到20多個訂單的進料單據,系統將單據分為三個狀態: 待收貨,收貨中,收貨完成
待收貨,收貨中的訂單要在屏幕上輪番顯示,但是屏幕最多只能顯示6行訂單,其余的隱藏,當第一行滾動消失,第二行替補上去,隱藏第一行顯示。效果圖如下:
整體數據往上滾動,當1 數據消失,3數據在最下面顯示。
二. 不同的開發人員如何去實現這個功能
(1)A 開發人員想法:
使用WinForm 或者 WPF去實現一個這樣的效果,特別是WPF實現的效果非常炫。最主要的是WinForm或者WPF對元素坐標的控制非常好,要使得內容移動只需要將其他的坐標處理移動就好了,然后加上一個線程或者定時器完全可以搞定。
(2)B 開發人員的想法:
最好使用Web頁面來實現,然后使用投影或者外接顯示器投到大屏幕。 Web實現的方式非常簡單,網上還有現成的案例,只需要修改樣式,顏色等就可以了,最關鍵的是web中可以使用jQuery,實現這樣的效果一點都不難。
(3)C 開發人員:
機場那個啥都是使用的LED屏幕,使用這個高端大氣上檔次,只要我們提供相應的數據,然后找一個LED屏供應商將數據顯示就可以了。
從以上三個人來看,對於同一個功能的實現都有着不同的看法,千萬不要認為這三種方案有什么問題,其實三種方案都能夠實現客戶所要的效果。
說明問題:一個問題的解決肯定不是沒有辦法或者只有唯一一種辦法。 以前我做程序的時候想問題也就局限在自己的思維邏輯中,除了這個就不會有什么更好的辦法去解決。
三. 三個技術人員的方案
先說A開發人員: 在功能正式開發之前讓A做了一個簡單的Demo, 但是做了幾天A還是停留在界面元素的控制上,而且文字的移動效果也不理想,跟別說后面的漂亮還要動態的去讀取數據等其他的操作了。 其實A對WinForm和WPF技術不是太了解,他只是想通過這個來加強一下自己的技能。 A的方案有點在於:界面元素的坐標可以嚴格控制,這樣在處理元素的移動的時候比較容易實現,缺點:因為界面的元素太多,而且內容在不斷的變化,所以最終頁不知道具體要處理哪個,理不清頭緒了。
再說B開發人員: 使用Web界面然后投影到屏上,我曾經作為技術人員,我也比較認可這種實現方式。 要實現這樣的一個效果其實也不是難事,jQuery中有動畫處理的函數,實現起來應該比較容易,而且網絡上有先天性的資源,可以解決一個大問題,看似非常完美的方案。事實上最終也是讓B來開發實現的。
C開發人員: C的想法有點脫離技術層面的考慮,A和B都直接提到了用什么編程技術,而C不是這樣的。所以說C的想法如果放到程序猿的眼中比較另類,但是C的確是最符合客戶索要的最直接解決方案,因為客戶不懂什么WinForm,WPF,jQuery。 但是C的方案沒有得到認可,對於重新安裝一個LED屏來說又是一筆開銷,而且客戶已經有現成的屏幕了[俗稱電視機]。
在第一次跟客戶談這個問題的解決方案的時候,我是比較認可C的想法的,剛才也已經說了C最能直接讓客戶理解和接受,客戶明白LED屏是怎么回事,不知道什么是WinForm,WPF,jQuery。 但是后來又否認了C的想法,問題要從客戶實際出發,利用好自己現有的資源和客戶的資源這個才是最重要的。首先公司的技術擅長的是Web方面的開發,而且客戶已經有閑置的屏幕,如果做LED還需要其他外部供應商。A的方案直接就槍斃了,首先給人的感覺就是技術方案不可行。
問題說明:
(1) 善於利用現有的資源(技術,人員,硬件,軟件,客戶), 軟件項目不只是將代碼寫完沒有BUG就完事了,寫代碼只是一個項目中非常少的一部分。
(2) 項目的開發要以實施為基准,一切的開發要以實施客戶使用為前提,當然如何開發是實施和技術之間是可以協調的,不存在一個壓倒另外一個說法。
(3) 開發人員的思維過於局限,或者說沒有真正去理解客戶的想法。
(4) 愚蠢的給客戶說你要告訴我明確的需求我才能給你開發。[這是我以前經常干的事情,從做了實施之后明白:客戶根本就不清楚自己的需求是什么,你要做的事情是幫客戶理清楚需求並且給他解決,否則你直接去做碼農,碼畜好了,你對客戶來說有什么價值]
(5) 網絡是工具,不是玩具,要善用網絡工具。
四. 技術問題
開始制定好以B的方案來解決這個問題,而且在正式開發之前B已經做好了一個Demo,說明技術問題已經解決了,要做的事如何完善這個東西。
(1) 頁面加載的數據行數不定,可能是3,4行,也可能超過10. 但是要求是如果超過6行數據,界面上顯示6行,然后循環滾動
(2) 界面的數據要從后台動態去讀取,並且定時更新
(3) 讀取訂單的數據不能直接到數據庫讀取
(4) 數據導出到Excel,然后人工去維護Excel中訂單狀態
因為功能的實現是使用jQuery方式來實現的,寫了一個jQuery方法來處理這個效果,簡單代碼如下:

var items = []; //定義一個數組 var currentIndex = limit; //當前要移除的對象索引 var total = 0; //顯示元素的所有個數 var height = $(this).find('> li:first').height(); //獲得每個條目的高度\ //將所有的元素存入數組中 $(this).find('> li').each(function (i, item) { items.push(item); }); total = items.length;//計算如上數組的長度 $(this).parent().css({ height: height * limit }); $(this).find('> li').filter(':gt(' + (limit - 1) + ')').remove(); var listItem = $(this); function Sky() { $(listItem).find('> li').filter(':lt(' + (limit) + ')').css({ opacity: 1, height: height }); $(listItem).find('> li').filter(':gt(' + (limit - 1) + ')').remove(); var $insert = $(items[currentIndex]).css({ height: 0, opacity: 0 }); $(listItem).append($insert); $(listItem).find("li:first").animate({ opacity: 0 }, 1000).animate({ height: 0 }, 1000, function () { $(this).remove(); }); $insert.animate({ height: height }, 1000).animate({ opacity: 1 }, 1000); currentIndex++; if (currentIndex >= total) { currentIndex = 0; } setTimeout(Sky, interval) }
問題1: B 人員測試使用的多於6行的數據處理的,而且數據不變更,效果非常好。現在出現了少於6行的數據,結果出現界面顯示的數據就少了1行[不是真正的少了,而是被影藏起來了]。 假設屬於有10行, 1-6顯示的時候 7-10影藏, 1 滾動消失,那么7顯示,1添加到最10的后面,一次類推。所以在少於6行的時候 比如3行數據,只能顯示2行了,而要求是3行都顯示才行。
問題2:當數據滾動時間較長的時候,因為動畫消失和上滾動的循環的時間頻率不一致,導致頁面出現滾動條,最后數據就亂了。
問題3:讀取Excel文件數據問題,B的反饋是如果Excel文件關閉讀取沒有問題,而打開之后時間讀取格式有問題
問題4:Excel內容變更如何通知界面數據改變
問題1-方案:
這個問題難度不大,只需要修改相應的判斷就可以了。如果所有的數據小於6行的時候,第一行顯示數據消失之后直接添加到末尾不處理影藏的效果。
問題2-方案:
這個問題將B難倒了,效果已經做好了,但是就是滾動頻率不一致,導致后面顯示的元素越來越多,界面上能夠看到的訂單多於6行了,而且出現頁面滾動條。最后還是我給他出了一個主意: 每次滾動變化的時候盤點顯示的內容是否已經超過了6行,如果是的那么設置其屬性影藏或者刪除該元素。
$(listItem).find('> li').filter(':gt(' + (limit - 1) + ')').remove();
這個問題折騰了B好多天,他一心想着要去調整滾動頻率和間隔時間,因為在你沒有完全計算准確的時候是很難讓兩者達到共振的效果的。跳出自己的思維模式可能問題很快就解決了。
問題3-方案:
這個也是困擾B非常長的一個問題,一直沒有解決。直到我看不過去了,我去看了他寫的代碼。
tempEntity.Forwarder = table.Rows[i][8].ToString(); Forecast = table.Rows[i][9].ToString();
第一句是讀取Excel中日期年月日部分的,客戶Excel中 一列是年月日,還有一列是 時間。 第二行是讀取時間的。現在的問題是,客戶要頻繁的去修改Excel中的內容,所以每次客戶打開Excel之后就不會去關閉這個Excel。
B就懵了,如果不關閉Excel,因為Excel被打開占用所以讀不出來數據。"被占用了讀不出來", 我不想說什么。我看了效果之后,打開Excel之后其他的數據都可以讀出來,就是時間日期這一列讀取出來不是日期格式,數據還是讀取出來了,是一個double類型的值。
我斷定這個問題與Excel是否被占用沒有關系,否則其他的數據可能也讀不出來,唯一的可能性就是Excel中的表格數據有問題或者是類型的問題。
這個讓我想到Excel中的一個現象,一個單元格中輸入一個很長的數字,當你編輯的時候會一一長串數字顯示,其他的時候會以科學計數法來顯示,這個時間應該和這個類似,確定應該是數據類型引起的。
DateTime date = DateTime.FromOADate(ConvertHelper.ToType<double>(Forecast) + ConvertHelper.ToType<double>(tempEntity.HHMM)); tempEntity.Forecast = date.ToString("MM.dd.yyyy"); tempEntity.HHMM = date.ToString("HH:mm");
我幫其調試問題,將以上幾個值取出來測試,發現這個值就是時間格式的另外一種計數方式,發現問題,問題解決。
問題4-方案
這個涉及到一個頻繁IO讀取Excel中的內容問題,頁面數據都從緩存中去讀取,Excel 更新替換緩存中的內容,避免去直接讀取Excel。
五. 經驗總結
(1) 技術人員除了發現問題之外還要去想辦法解決,很多人很容易找問題,但是很難去解決問題。
(2) 使用推理分析的方法去確定問題在哪里,對症下葯。
(3) 善於傾聽其他人的意見,融合大家的想法可以更好的去解決一個問題。
(4) 開發人員不要活在自己想象的世界里面,去學習了解一下別人的想法可能對你有很大的幫助。
(5) 寫軟件最重要的實用,好用。技術的本質是解決問題而不是看哪個界面做的更加漂亮或者使用了多少新的技術。
(6) 技術的選用要符合實際,切莫隨波逐流,最終項目失敗抱憾不已。
(7) 多接觸用戶,聽聽用戶的反饋,自己也實際去操作一下,你才能真正感受到用戶的想法,你才能理出客戶的需求。
六. 感觸的一句話
沒有玩過智能手機的程序員去做移動開發