讀阿里巴巴Java開發手冊v1.2.0之工程結構有感【架構篇】


首先,把昨天那倆條sql語句的優化原因給大家補充一下,第一條效率極低,第二條優化后的,sql語句截圖如下:

經過幾個高手的評論和個人的分析:

  第一條sql語句查詢很慢是因為它首先使用了in關鍵字查詢,導致全表掃描,其次我那條sql語句的寫法上,是通過子查詢根據某一個字段去不斷匹配后面查詢到的集合數據,最后得到查詢結果,這一系列操作下來效率上去才怪呢。

  但是第二條sql語句是通過連接查詢,根據建立了索引的字段來等值匹配,最后得到查詢結果,速度杠杠的。(一次小小的優化經歷,學到了)。

 

  今天(2017-05-24)在微信公眾號上終於等到阿里巴巴集團開源的Java開發手冊更新了,從地鐵上一路看到公司,真的學到了,人家的開發規約真的是好,講的很細,很注重細節,這就是差距啊,下面給大家簡單總結一下吧(手冊原件如果需要,請留言)。

  它的名字是《阿里巴巴Java開發手冊v1.2.0》,距2017-02-09發布的第一版已經有6個歷史了,它的總體結構分為五大部分:編程規約、異常日志、MySQL數據庫、工程結構和安全規約。今天我主要給大家分享總結了工程結構,因為我五一前剛給公司開發了一套內網數據錄入系統,雖然沒用到什么大的框架和潮流的技術,但是麻雀雖小五臟俱全啊。包括表結構、工程搭建和業務梳理都是自己一個人在開發,當時在開發的時候也是感覺很孤獨,因為項目組的其他人都有戰友配合作戰,而我就一個人,還有頁面的調試和美化都是我一個人在搞,在此聲明一下,我不是在抱怨,反而很珍惜這種開發機會,真的會沉淀很多東西,謝謝公司。

  切入正題吧,今天給大家分享的是工程結構這塊的一些個人總結。

1、項目應用分層:

這里主要給我們講述了一下,一個項目理想化的項目架構圖,和我們平時開發的項目結構稍稍不同,畢竟人家的架構思維那是相當的高啊,這還是最基礎的架構圖呢。

上圖默認上層依賴於下層,箭頭關系表示直接依賴。

  開放接口層:可直接封裝service層接口中的方法暴露成RPC接口/服務,通過web封裝成http接口,最后進行網管控制、流量控制等。

  終端顯示層:各個端的模板渲染並執行顯示的層。當前我們主要接觸的是js渲染、jsp渲染和移動端渲染等。

  web層:主要是對訪問控制進行轉發,各類基本參數校驗,或者不復用的業務簡單處理等。

  service層:相對具體的業務邏輯服務層。

  manager層:通用業務處理層,它有如下特征:1、對第三方平台封裝的層,預處理返回結果及轉化異常信息;2、對service層通用能力的下沉,比如緩存方案、中間件通用處理、3、與dao層交互,對多個dao的組合復用。

  dao層:數據訪問層,與底層MySQL、Oracle、hbase數據庫進行數據交互。

  外部接口或第三方平台:包括其他部門的rpc接口,基礎平台,其他公司的http接口。

 

  以上都是阿里項目的工程架構,有一點不同的是我們平時通用的是controller層、service服務層和dao數據訪問層,但是他們這里提出了manager層,將一些業務通用的處理方式和需要多個dao組合復用的結果抽取到該層,個人感覺在項目維護上很方便,以前我們都是按模塊划分,將各個模塊的業務邏輯都往service層堆上去,這樣其實也沒什么不好,但是我們感覺試着將業務層通用的業務抽取一下,剛才還琢磨着把我前倆天寫的項目重構一下,最后還是等到端午吧,也好好模仿一把阿里,哈哈哈。

2、項目異常分層處理規約:

  因為dao數據訪問層產生的異常很多,類型也很多,無法用細粒度的異常進行處理,所以直接將異常丟給service層,為啥要將數據訪問層的異常丟到manager/service層,因為通常在manager/service層中會有日志打印,不管是發生異常還是異常拋出,都會時刻記錄運行情況到日志文件中去,要是剛才在dao層也將異常打印,又因為dao和service是同台服務器,這樣就相當於打印了2次日志,浪費性能和儲存。

  service產生的異常必須記錄到磁盤日志文件中去,盡可能帶上參數信息,相當於保護案發現場。

  web層大哥們,不能在爽啦,必須處理了,如果產生的異常會導致頁面的正常渲染,則采用攔截器或異常處理的方式,跳轉到異常錯誤友好頁面,加上友好的錯誤提示信息,最后還要在開發接口層將產生的異常處理成錯誤碼和錯誤信息返回。

3、分層領域模型規約:

  我們以前的項目中我見過有3類模型類,第一類是web層與視圖層傳遞參數的query類,第二類是與數據表對應的pojo類,第三類是為了響應數據定義的擴展vo類。

  下面我們來看看阿里是如何將模型進行規約的,我感覺非常啰嗦但是非常好,其實很多電商公司也估計是這么做的,我之前接觸的一個電商項目大概就是這種設計,好長時間了記不清了:

  DO(data object):與數據庫中的數據表一一對應,通常是應用於數據訪問層dao中用於向上傳輸數據源對象。

  DTO(data transfer object):數據傳輸對象,該模型類主要是應用於service層和manager層,將service層和manager層業務處理后進行向外傳輸對象。

  BO(business object):業務對象,主要是service層輸出的封裝的業務邏輯的對象。

  Query:數據查詢對象,各層接受上層傳遞過來的多個參數並將這些參數封裝到query對象中。

  VO(view object):視圖層對象,主要是web層向視圖層傳輸的數據對象。

4、二方庫依賴:

  定義GAV遵從一下規則:

  (1)、GroupID格式:com.{公司/BU}.業務線.[子業務線],最多四級。

  (2)、ArtifactID格式:產品線名-模塊名。注意:語意不重復不遺漏,最好到中央倉庫中去查證一下。

  (3)、Version格式:版本號根據自己公司的規定。

 

最后給大家送上幾條建議,也是在手冊中看到的,只不過寫到這兒印象比較深刻,還沒忘就給大家寫在這兒吧:

一:數據訂正時,在調用修改和刪除方法之前,最好先查詢要修改或刪除的記錄是否存在,確認無誤后再進行更新。

二:在查詢數據時能避免使用IN關鍵字就避免,是在避免不了,則需要仔細評估IN后邊的數據集合中總數是否超過1000,最好控制在1000以內,我上次的優化經歷起源於它,就是匹配的集合數據遠遠超過1000條,最后導致查詢效率極低。

三:sql.xml文件中配置參數盡量使用#{},盡量不要使用${},容易造成sql注入問題。

四:接口過時必須加@Deprecated注釋,並且添加注釋清晰地說明替代舊接口的新接口或服務。

五:一般不要在pojo類中定義屬性的變量時,建議不要加is前綴,但是在數據表中定義屬性對應的字段是盡量加上is_前綴,原因是:如果在給屬性的變量名加上is前綴極可能會發生,部分框架解析時會引起序列化錯誤。

六:在定義項目中的包結構時,統一使用小寫並單數形式。

七:service層和mapper接口中定義的方法,建議不要寫修飾符,目的就是代碼結構看着簡單,阿里給出的解釋,所以我就把我以前的都刪掉了,好習慣就應該從現在開始。

八:如果項目中要實現分頁邏輯,如果在判斷總記錄數為0時,則直接返回,避免執行后面的分頁語句,給大家送張截圖,是我前幾天自己寫的分頁邏輯:

1   @Override
2     public List<Task> findOrdersByUserId(Task task,Page page) {
3         int count = vinTaskMapper.countOrdersByUserId(task);
4         page.setMaxRow(count);
5         if(count == 0){
6             return new ArrayList<Task>();
7         }
8         return vinTaskMapper.findOrdersByUserId(task,page);
9     }

九:禁止使用存儲過程,因為難以調試和擴展,更沒有移植性。

 

好了,就總結到這兒吧,這里雖然沒什么干貨和技術要點,但是我的目的是給大家分享一點編程習慣,具備好的代碼風格是作為一個優秀程序員的基本素能,最后希望大家寫出來的代碼能夠越看越美,越看越想看,哈哈哈。

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM