從一名技術開發人員到實施人員的蛻變,從不同的角度看待同一個問題,或許會有不一樣的結果。這裡記錄一下最近一個專案實施的案例,非常有感觸!
一. 專案情況簡介
本次專案是給一個國外生產型企業做倉庫方面的系統,其中有一個功能就是給倉庫做一個電子看板。所謂的電子看板就是在一個大螢幕上顯示倉庫進料和出料的情況,在大螢幕上顯示指定數量的單號資訊,就和醫院的叫號系統一樣,每行資料不停的向上滾動。
上面這個功能其實非常簡單,就是查詢相應的資料在螢幕上顯示即可. 倉庫每天可能收到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) 多接觸使用者,聽聽使用者的反饋,自己也實際去操作一下,你才能真正感受到使用者的想法,你才能理出客戶的需求。
六. 感觸的一句話
沒有玩過智慧手機的程式設計師去做移動開發