上一錘提到了剛發(fā)布的免費ERP系統(tǒng)(www.2bizbox.com)后,大家反響很熱烈,短短3天就被下載了2萬多次,服務器一度宕機,呵呵。大家討論也比較熱烈,紛紛提出不少問題和技術探討,感覺非常有意義。這次和大家分享一下關于這個免費ERP的架構設計。之前先回答一下大家比較關心的一些問題:
還是來說說架構。先看這個圖就都明白了。
提到架構,我們用到的第三方的框架不是很多,總的原則就是盡量簡單、穩(wěn)固。這樣,就會高效、好維護。這遠比一些烏七八糟的所謂新思想新技術更加重要,畢竟我們的軟件要維護幾十年的(實際上已經(jīng)從DOS到現(xiàn)在開發(fā)了20年了)。后臺主要是JBoss和Hibernate,其他大部分部分都是自己封裝。前臺則基于Swing以及自己封裝的各種組件。中間通訊也沒有采用第三方的框架,而是自己封裝,主要采用HTTP協(xié)議,對交換的VO(包括VO集合)對象(如參數(shù)、返回值、Exception等)進行標準的Java二進制序列化、zip壓縮、傳輸。調(diào)用的方法通過一個統(tǒng)一的invoke進行傳遞,被調(diào)用的模塊、方法名、參數(shù)等,都被封裝在一個POJO中傳給后臺。后臺Façade層解壓后,根據(jù)具體模塊,通過反射的方法,調(diào)用Local的各個模塊EJB,執(zhí)行具體函數(shù)。每個函數(shù)先在Biz業(yè)務層進行業(yè)務邏輯分解處理,例如,如果要添加一個零件,要分解很多具體動作,先檢查零件號是否重復,再檢查零件號是否格式合法,數(shù)據(jù)是否完備,創(chuàng)建零件庫存初始信息、創(chuàng)建物料添加日志、通知相關人員…等等。分解后,形成具體的DAO操作,然后交給DAO進行調(diào)用相應的底層API完成。無數(shù)的DAO對各個業(yè)務數(shù)據(jù)進行各種數(shù)據(jù)級別的操作封裝(增刪改查等),然后通過Hibernate層進入數(shù)據(jù)庫。
有朋友喜歡用Eclipse RCP來作為前臺框架。坦白說,我個人對SWT一向不喜歡,也不看好,因為他本質上和AWT的路線沒什么不同,只是后臺老板從SUN換成了IBM。當初以“好看+效率高”的旗號,SWT曾經(jīng)風靡一時,人人趨之若鶩。不過本質上說,SWT這種技術是打著“好看/速度快”幌子分裂JAVA的政治游戲,我們程序員應當看清楚。當然不是說SWT技術不好不能做企業(yè)應用,實際上我認識的一些朋友已經(jīng)用SWT搭建了好大好大的應用。不過SWT畢竟不是JAVA的官方技術。如果相信JAVA的未來的話,我覺著應當相信SWING才是正道。SWING有不足,但是它會不停的發(fā)展。另外,千萬別總拿“丑”和“慢”來攻擊Swing,說到底還是看你會不會用,吐口水實在無意+無聊。說道RCP框架,我倒更喜歡NetBeans。不過國內(nèi)大家還是把Netbeans當做IDE來用,實際上這個RCP平臺相當不簡單,質量很高而且國外應用很多,已經(jīng)非常成熟,有空可以多看看Netbeans的Platform頻道(不是IDE哦)。
HttpInvoker沒有用過,不知是不是和Spring綁的比較死,看上去和我們的通訊方式完全類似。其實java序列化再傳輸就是幾行代碼的事情,如果不用Spring等框架,完全沒必要用第三方的,自己封裝一下就好了。看看這個代碼就知道了:
Hessian基于WS還可以支持不同的客戶端,也很不錯。不過我們這種需求不大,沒有使用WS以及其他客戶端技術的需求,也沒有采用。還是覺著簡單的東西自己封裝更加的靈活和容易控制。我們的思路是盡量少的引進第三方的框架。過多的異構框架導致的穩(wěn)定性和靈活性的代價也是很大的。
其他一些類似MQ之類的異步框架就更比較謹慎使用。前后臺調(diào)用需要實時性,肯定是同步調(diào)用為主。異步的情況不多,即使有,在基于HTTP的結構下(例如只開放80端口)也比較難實現(xiàn)。我們采用了JBOSS的JMS機制,實現(xiàn)一些后臺主動發(fā)送業(yè)務消息、上傳圖紙等功能。當然如果后臺禁止了相應端口,客戶端就自動放棄JMS連接,工作在純“主動模式”下,相當于一個“瀏覽器”。
對于非桌面客戶端,例如手機、數(shù)據(jù)采集器、PDA等,我們在后臺的Façade層上面再包裝一個又一個簡單的“協(xié)議適配”就行了,也就是把Java的對象簡單的封裝到XML或HTML,負責與這類終端通訊。這樣,身后的安全啊、日志啊、業(yè)務啊等就完全復用,開發(fā)速度是很快的。對于大多手機,使用XHTML進行瀏覽即可;對于iPhone等則開發(fā)native的終端,對于PDA和數(shù)據(jù)采集器,由于有條形碼、收料發(fā)料、盤點等復雜應用,所以用本地的環(huán)境進行創(chuàng)建GUI(一般都是Windows CE,可用C#進行)。這樣,我們的架構可以簡單快速的支持各種不同的終端接入:
有朋友擔心一個Servlet提供所有API太變態(tài),其實不必擔心。沒錯,我們的模塊API至少上萬,但是這個后臺的Façade Servlet其實只有不超過10個方法。最主要的一個是invoke,方法都是通過一個對象封裝了模塊、方法名、參數(shù)序列等來通過反射機制完成的,所以,無論后臺模塊API有多少,只要通過這一個唯一的業(yè)務入口出入就行了。至于前臺使用不太方便的問題,可以通過前臺再次封裝展開來解決。
最后送Swing界面:設置會計年度