天天看點

JAVA開發規範

 貼一份我之前整理的 java開發規範:

java開發規範

[email protected]

代碼整體風格             

controller類,不要直接使用map,httpservletrequest request,httpservletresponse response 作為參數,不要使用 servlet api的接口          

一個service類不應該引用其他service類,但是可以引用多個dao層對象

mapper類應該盡量輕量級,不要過多的自定義sql

使用beanutil,而不是setxxx(info.getxxx)                       

避免重複代碼,代碼段出現過3次,一定要提取更多的公共代碼到基礎層, 比如mint

方法不超過200行,一個類不超過1000                      

看到醜陋代碼, 重構它!時不時 重構!                  

使用設計模式!

代碼要 提高 複用, 但是不能複制,複制一時爽,但是并不能提高 複用性!~      

對自己做的子產品負責, 對其業務邏輯要一清二楚! 否則就 不合格~@!         

面向對象程式設計,更重要的是 面向接口

同一個含義的枚舉, 全局應該隻出現一次,而不是每個子產品一次, 否則改起來還是很麻煩!避免枚舉類泛濫

不要動不動就mq,避免消息泛濫

不超過3層 if else                   

專業術語的 英文名字要統一,簡寫也要統一 

一般情況下,方法簽名不要抛出異常,除非涉及資源的工具類 !

不應該使用 寫死

提高 内聚, 降低耦合! 不要一個service就一個方法, 不要引用太多其他的service, 分得太散了就會 導緻 太松散,内聚性太差! 看代碼,調試都會很痛苦!

杜絕代碼壞味道!啰嗦 / 低級 / 重複代碼, 一概拒絕!

能夠提取的, 一定要提取到公共位置, 杜絕 複制黏貼, 杜絕醜陋代碼!

代碼保持簡單,靈活,複用性,獨立,高内聚,低耦合

每個方法要 邏輯十厘清晰, 一目了然

代碼應該清晰可讀,盡量保持簡單易讀

統一的code style

不要為了 微服務而 微服務 !

大家使用統一的規範,友善交流,減少維護成本             

服務分層、命名規範        

服務名\服務名-api\src\main\java\com\wisdom\服務名\                                                   

         service              所有的服務接口,統一字首為i,字尾為 service                          

                   子子產品名x                                 

                            ixxxservice                         

                   子子產品名y                                 

                   imainxxx1service    不要出現         xxxparam、 xxxsearch

                   imainxxx2service   

                   imainxxx3service                               

                   bank other service                     

     dto            所有的前後端互動對象,統一字尾為 dto

         exception                  所有的自定義異常,應該繼承于運作時異常,統一字尾為exception                      

服務名\服務名-provider\src\main\java\com\wisdom\服務名\                                                  

         common           所有全局的共享東西:所有的常量、枚舉、靜态類,包括各種工具類,redis、mq通路工具類                         

                   constants         目前服務共用的常量類                  

                   xxxutil               目前服務共用的工具類                  

                   xxxbaseservice        目前服務共用的服務類                  

                   xxxredisutil              目前服務共用的redis工具類                

                   xxxrabbitmqutil      目前服務共用的mq工具類          

                   xxxconfig          示例:com.wisdom.jasmine.mvc.checklogininterceptor

                   xxxhandler       示例:com.wisdom.jasmine.mvc.globalexceptionhandler

xxxexception 特有的異常類

         service              處理業務邏輯,所有的服務接口實作類,統一字尾為 serviceimpl,如有必要,下面還可以建立一層package,表明子子產品名,但是package不宜太深                      

                            xxxserviceimpl                           

                            yyyserviceimpl                           

                   mainxxx1serviceimpl                                  

                   mainxxx2serviceimpl                                  

                   mainxxx3serviceimpl                                  

         mapper             所有的資料庫通路類,統一字尾為mapper                         

                   xxxmapper                                  

                   yyymapper                         隻有複雜的 查詢sql, 不應該有修改、新增、删除sql

         model                所有的資料庫實體映射類,統一字尾為model                   

                  xxxmodel                           

                   yyymodel

  message  後端和mq 互動的pojo,盡量少使用,應該使用dto

web層就是controller層,直接前端對接項目,服務名一定要有一個 web 字尾

服務名\服務名-web\src\main\java\com\wisdom\服務名\                                                          

         controller          處理視圖,所有的controller類,統一字尾為 controller                           

                   xxxcontroller                              

api 服務的dto,provider服務的model 應該不相同,否則考慮是否服務沒定義 / 劃分好。

每個表對應一個model,一個mapper。但不需要每一個model 一個service,比如一些關聯表的查詢/新增/修改/删除操作,直接在主表對于的service完成。

每個service應該有對應的一個主表。但有時候也可能有多個。

一般情況下,service和mapper和model和資料庫表 同名。

xxxparam、 xxxsearch、xxxmessage 不能忘文知義,增加溝通成本,而且轉換起來很麻煩。

為什麼service層不能調用其它service?               

比較清晰的單向關聯:

JAVA開發規範

n向關聯(可能存在循環依賴):

JAVA開發規範

一般命名規範

controller層

service層

dao層

query/page

getone

selectone

擷取單個實體,參數就是實體本身

getbyyyy

selectbyid

按照id擷取單個實體

list

page

selectbyxxx

按照某條件擷取單個實體,參數就是實體某個字段

按照某條件,擷取實體的list集合

listall

selectall

傳回所有行

add

insert

新增單個實體。不存在 insertbyxxx 方法

modify

update

更新單個實體

updatebyxxx

這個情況少見, 一般是通過id 進行更新

save

新增或修改, 不需要saveorupdate 方法名

業務方法

相同 業務方法

 相同或不需要

service 層:

list擷取實體的list集合

page 分頁查詢,統一傳回, pageinfo<實體model>

資料流轉:

資料庫層命名規範             

字段使用要統一, state、status、                                統一 status

表: 表的業務含義應該清晰明确, 不宜使用過多字段。<  30 ..                

princ         inter

不要這樣引起誤會的縮寫,        

要麼就不使用縮寫,而是全寫,要麼使用通用的縮寫,        

pom 規範             

         pom 提取公共配置 commons                        

         使用最少的dependency,盡量從parent中繼承                          

         依賴應該盡量簡化                           

         需要仔細考慮每一個dependency 是否是必須的

注釋規範              

         每個類寫明 用途、注釋、作者、關聯                         

         每次修改 寫明原因、作者、時間      

/**

 * 這個類是為了做什麼,主要用途是abc

 *

 * @author lk([email protected])

 * @time 2018-12-29

 */

javadoc 注釋标簽文法

@author   對類的說明 标明開發該類子產品的作者

@version   對類的說明 标明該類子產品的版本

@see     對類、屬性、方法的說明 參考轉向,也就是相關主題

@param    對方法的說明 對方法中某參數的說明

@return   對方法的說明 對方法傳回值的說明

@exception  對方法的說明 對方法可能抛出的異常進行說明

日志規範              

         了解和使用 debug、info、warn、error 各個級别,一般日志使用info基本,捕捉到錯誤如果要記錄異常,必須使用 error 級别。

異常處理規範             

controller 做主要的參數檢驗,空指針檢查。不做具體的異常處理, 異常處理統一到mvc的exceptionhandler

service層捕捉所有的已知異常(受檢異常),對系統異常封裝傳回,對業務異常傳回錯誤碼和錯誤資訊,空指針檢查。(處理已知異常,運作時異常不用管)

dao/mapper 不捕捉異常      

盡量不要try catch(exception e) 這個由統一的mvc的exceptionhandler 來做

不合理的示例                             

mapper.attachmentmapper#deleteattachmentbyobject 方法是不是可以簡化為 delete ?

mapper.attachmentmapper#querybyobject                      querybyobject -> query

provider.repayoverdueprovider#insertorupdatecommit 奇怪的命名

provider.creditoradvanceprovider           provider 是什麼? service 還是dao?

lock.lockkeys                              lock 一個package 隻有一個類, 是不是放到 constants 更好?

invite.enums.querydatetypeenum         enums 是不是放到 constants 更好?

invite.utils.activityinviteutil                      不需要單獨建立util 包                                    

product.utils.uploadutils                           uploadutils 并不是 product 才有的一個工具類

product.service.impl.productserviceimpl        provider 服務 使用service 還是 service.impl ? 至少應該是統一

domain.custom.collectioncalendarview                                             

search.creditoradvancesearch                                           

com.wisdom.daffodil.model.bank.bindcardreq     不要搞特殊化,統一使用dto就好

阿裡巴巴規範             

         【強制】pojo 類中布爾類型的變量,都不要加 is ,否則部分架構解析會引起序列化錯誤。                          

         【強制】不要使用一個常量類維護所有常量,應該按常量功能進行歸類,分開維護                           

         【強制】所有的覆寫方法,必須加@ override 注解。                      

         【強制】所有的相同類型的包裝類對象之間值的比較,全部使用 equals 方法比較。                        

         【強制】關于基本資料類型與包裝資料類型的使用标準如下:                      

                   1 ) 所有的 pojo 類屬性必須使用包裝資料類型。               

                   2 ) rpc 方法的傳回值和參數必須使用包裝資料類型。               

                   3 ) 所有的局部變量【推薦】使用基本資料類型。               

         【強制】定義 do / dto / vo 等 pojo 類時,不要設定任何屬性預設值。                           

         【強制】 pojo 類必須寫 tostring 方法。使用 ide 的中工具: source > generate ,tostring時,如果繼承了另一個 pojo 類,注意在前面加一下 super.tostring 。                       

         【強制】關于 hashcode 和 equals 的處理,遵循如下規則:                        

                   1) 隻要重寫 equals ,就必須重寫 hashcode 。          

                   2) 因為 set 存儲的是不重複的對象,依據 hashcode 和 equals 進行判斷,是以 set 存儲的對象必須重寫這兩個方法。                  

                   3) 如果自定義對象做為 map 的鍵,那麼必須重寫 hashcode 和 equals 。           

         【強制】 arraylist 的 sublist 結果不可強轉成 arraylist , 否則會抛出 classcastexception異常: java . util . randomaccesssublist cannot be cast to java . util . arraylist ;                       

         【強制】 在 sublist 場景中,高度注意對原集合元素個數的修改,會導緻子清單的周遊、增加、删除均産生 concurrentmodificationexception 異常。                      

         【強制】使用工具類 arrays . aslist() 把數組轉換成集合時,不能使用其修改集合相關的方法,它的 add / remove / clear 方法會抛出unsupportedoperationexception 異常。                      

         【強制】線程資源必須通過線程池提供,不允許在應用中自行顯式建立線程。                           

         【強制】線程池不允許使用 executors 去建立,而是通過 threadpoolexecutor 的方式,這樣的處理方式讓寫的同學更加明确線程池的運作規則,規避資源耗盡的風險。                           

         【強制】 simpledateformat 是線程不安全的類,一般不要定義為 static 變量,如果定義為                         

                   static ,必須加鎖,或者使用 dateutils 工具類。          

         【強制】對多個資源、資料庫表、對象同時加鎖時,需要保持一緻的加鎖順序,否則可能會造成死鎖。                      

         【強制】多線程并行處理定時任務時, timer 運作多個 timetask 時,隻要其中之一沒有捕獲抛出的異常,其它任務便會自動終止運作,使用 scheduledexecutorservice 則沒有這個問題。                         

         【強制】在一個 switch 塊内,每個 case 要麼通過 break / return 等來終止,要麼注釋說明程式将繼續執行到哪一個 case 為止 ; 在一個 switch 塊内,都必須包含一個 default 語句并且放在最後,即使它什麼代碼也沒有。                     

         【強制】不要捕獲 java 類庫中定義的繼承自 runtimeexception 的運作時異常類,如:                          

                   indexoutofboundsexception / nullpointerexception,這類異常由程式員預檢查              

                   來規避,保證程式健壯性。                  

         【強制】異常不要用來做流程控制,條件控制,因為異常的處理效率比條件分支低。                      

         【強制】對大段代碼進行try-catch,這是不負責任的表現。catch時請厘清穩定代碼和非穩定代碼,穩定代碼指的是無論如何不會出錯的代碼。對于非穩定代碼的catch盡可能進行區分異常類型,再做對應的異常處理。                   

         【強制】捕獲異常是為了處理它,不要捕獲了卻什麼都不處理而抛棄之,如果不想處理它,請将該異常抛給它的調用者。最外層的業務使用者,必須處理異常,将其轉化為使用者可以了解的内容。                           

         【參考】在代碼中使用“抛異常”還是“傳回錯誤碼”,對于公司外的http/api開放接口必須使用“錯誤碼”;而應用内部推薦異常抛出;跨應用間rpc調用優先考慮使用result方式,封裝issuccess()方法、“錯誤碼”、“錯誤簡短資訊”。