軟件研發代碼規範

1. 分支開發流程

  1. GIT分支開發規範,具體請參考:www.jianshu.com/p/cbd8cf5e2…

2. 代碼規範

  1. 主要使用Java語言來進行開發,嚴格遵循Sun公司的Java編碼規範。此外還有如下補充。

2.1 大小寫

  1. 常量的字母 所有大寫,單詞之間用一個 下劃線字符(_) 進行分隔。
  2. 除常量外的命名 採用大小寫混合,提升名字的可讀性。
  3. 通常採用小寫字母,可是類和接口的名字的首字母,以及任何中間單詞的 首字母應該大寫

2.2 編碼格式

  1. 確保IDE工做環境使用UTF-8編碼格式。
  2. 縮進一概使用空格而非Tab。
  3. 縮進一概採用4空格。能夠設置IDE 1Tab=4空格。
  4. 對於非第一次建立的代碼文件,禁止作reformate操做,這個操做會破壞代碼的修改歷史,形成大機率的push、merge、pull等操做衝突。

2.3 常量定義

  1. 對具備特殊意義的數字或字符要以常量的形式定義,並說明常量所表示的意義,避免幻數的出現。

2.4 統必定義公共常量

  1. 對於一些公共常量的使用,應該單獨定義相應的常量類,並統一使用,避免在各業務類、功能類中分別定義、直接使用。

2.5 命名規則

  1. Package: 1.1 Package: 每個包的名稱老是小寫,暫定將com.keegoo.+(模塊名)做爲總前綴,好比com.keegoo.demo.blog.service、com.keegoo.demo.blog.dto; 1.2 明確不一樣業務建議創建子package,好比有關User業務的:com.keegoo.user.account.service、com.keegoo.user.account.dto;編程

  2. Class類:類名必須是名詞,且以大寫字母開頭。類名應該簡單清晰。緩存

  3. Interface類: 3.1 Interface命名上,暫定以XxxService的形式提供; 3.2 最終提供的接口應以Java Interface的形式出現; 3.3 每一個獨立的業務的Interface應該有獨立的package包,一個package下可包含該業務模塊下的多個Interface; 3.4 每一個Interface的一個方法對應所謂的一個「中間層服務接口」,須要按照規範書寫該接口的說明;工具

  4. 緩存命名規則:對緩存的key要採用命名空間,以免衝突,同時要考慮緩存的命中率,不要浪費緩存的空間。性能

2.6 Controller,Interface類,接口實現類編寫注意事項

  1. Controller類裏不能出現業務邏輯,只能直接調用Service類,不能直接調用Biz類(Biz類是對業務邏輯的實現封裝,不依賴dao層,可獨立作單元測試),manager類則是做爲service、biz、dao三層的粘合劑,來協調三者執行關係。
  2. Interface接口定義類只定義方法,方法的實現要在實現類裏完成,interface接口以xxxService結尾,接口實現類以xxxServiceImpl結尾。

2.7 註釋

  1. 方法註釋:每一個接口、方法應該有一個方法的總體說明,包括方法實現的功能、參數的詳細含義、返回值的取值及其詳細含義。
  2. 類註釋:對於工具類或者流程類,須要在類的註釋中對於類的功能進行詳細的說明;對於Model類,要對其重要的屬性添加註釋,註明其含義,必要時要重載hashCode和equals,toString方法。

3. 設計規範

3.1 對功能性模塊的抽象

業務模塊的開發過程當中,應該避免過長的方法,進行合理的功能模塊的提取以及抽象,避免同一段代碼、相似代碼處處copy的狀況。單元測試

3.2 單一職責原則SRP(Single Responsibility Principle)

所謂單一職責原則,指的就是:一個類應該僅有一個引發它變化的緣由。測試

這裏變化的緣由就是 所說的「職責」,若是一個類有多個引發它變化的緣由,那麼也就意味着這個類有多個職責,再進一步說,就是把多個職責耦合在一塊兒了。這會形成職責的相互影響,可能一個職責的變化,會影響到其它職責的實現,甚至引發其它職責跟着變化,這種設計是很脆弱的。編碼

這個原則看起來是最簡單和最好理解的,可是其實是很難徹底作到的,難點在於如何區分這個「職責」,這是個沒有標準量化的東西,哪些算職責,到底這個職責有多大的粒度,這個職責如何細化等等。所以,在實際開發中,這個原則也是最容易違反的。設計

3.3 開放-關閉原則OCP(Open-Closed Principle)

所謂開放-關閉原則,指的就是:一個類應該對擴展開放,對修改關閉。通常也被簡稱爲開閉原則,開閉原則是設計中很是核心的一個原則。調試

開閉原則要求的是,類的行爲是能夠擴展的,並且是在不修改已有的代碼的狀況下進行擴展,也沒必要改動已有的源代碼或者二進制代碼。日誌

看起來好像是矛盾的,怎麼樣才能實現呢?

實現開閉原則的關鍵就在於合理的抽象,分離出變化與不變化的部分,爲變化的部分預留下可擴展的方式,好比:鉤子方法、或是動態組合對象等等。

這個原則看起來也很簡單,但事實上,一個系統要所有作到遵照開閉原則,幾乎是不可能的,也沒這個必要。適度的抽象能夠提升系統的靈活性,使其可擴展、可維護,可是過分的抽象,會大大增長系統的複雜程度。應該在須要改變的地方應用開閉原則就能夠了,而不用處處使用,從而陷入過分設計。

3.4 里氏替換原則LSP(Liskov Substitution Principle)

所謂里氏替換原則,指的就是:子類型必須可以替換掉它們的父類型。這很明顯是一種多態的使用狀況,它能夠避免在多態的應用中,出現某些隱蔽的錯誤。

事實上,當一個類繼承了另一個類,那麼子類就擁有了父類中能夠繼承下來的屬性和操做,理論上來講,此時使用子類型去替換掉父類型,應該不會引發原來使用父類型的程序出現錯誤。

可是,很不幸的是,在某些狀況下是會出現問題的,好比:若是子類型覆蓋了父類型的某些方法,或者是子類型修改了父類型某些屬性的值,那麼原來使用父類型的程序就可能會出現錯誤,由於在運行期間,從表面上看,它調用的是父類型的方法,須要的是父類型方法實現的功能,可是實際運行調用的確是子類型覆蓋實現的方法,而該方法跟父類型的方法並不同,那就會致使錯誤的產生

從另一個角度來講,里氏替換原則是實現開閉的主要原則之一,開閉原則要求對擴展開放,擴展的一個實現手段就是使用繼承,而里氏替換原則是保證子類型可以正確替換父類型,只有能正確替換,才能實現擴展,不然擴展了也會出現錯誤

3.5 依賴倒置原則DIP(Dependence Inversion Principle)

所謂依賴倒置原則,指的就是:要依賴於抽象,不要依賴於具體類。要作到依賴倒置,典型的應該作到:

  1. 高層模塊不該該依賴於底層模塊,兩者都應該依賴於抽象;
  2. 抽象不該該依賴於具體實現,具體實現應該依賴於抽象;

不少人以爲,層次化調用的時候,應該是高層調用「底層所擁有的接口」,這是一種典型的誤解。事實上,通常高層模塊包含對業務功能的處理和業務策略選擇,應該被重用,應該是高層模塊去影響底層的具體實現

所以,這個底層的接口,應該是由高層提出的,而後由底層實現的,也就是說底層的接口的全部權在高層模塊,所以是一種全部權的倒置。

倒置接口全部權,這就是著名的Hollywood(好萊塢)原則:不要找咱們,咱們會聯繫你

3.6 接口隔離原則ISP(Interface Segregation Principle)

所謂接口隔離原則,指的就是:不該該強迫客戶依賴於他們不用的方法

這個原則用來處理那些比較「龐大」的接口,這種接口一般會有較多的操做聲明,涉及到不少的職責。客戶在使用這樣的接口的時候,一般會有不少它不須要的方法,這些方法對於客戶來說,就是一種接口污染,至關於強迫用戶在一大堆「垃圾方法」裏面去尋找他須要的方法

所以,這樣的接口應該被分離,應該按照不一樣的客戶須要來分離成爲針對客戶的接口,這樣的接口裏面,只包含客戶須要的操做聲明,這樣既方便了客戶的使用,也能夠避免因誤用接口而致使的錯誤。

分離接口的方式,除了直接進行代碼分離以外,還可使用委託來分離接口,在可以支持多重繼承的語言裏面,還能夠採用多重繼承的方式進行分離。

3.7 最少知識原則(Least Knowledge Principle)

所謂最少知識原則,指的就是:只和你的朋友談話

這個原則用來指導咱們在設計系統的時候,應該儘可能減小對象之間的交互,對象只和本身的朋友談話,也就是隻和本身的朋友交互,從而鬆散類之間的耦合。經過鬆散類之間的耦合來下降類之間的相互依賴,這樣在修改系統的某一個部分時候,就不會影響其它的部分,從而使得系統具備更好的可維護性。

那麼究竟哪些對象才能被看成朋友呢?最少知識原則提供了一些指導:

當前對象自己;

經過方法的參數傳遞進來的對象;

當前對象所建立的對象;

當前對象的實例變量所引用的對象;

方法內所建立或實例化的對象;

總之,最少知識原則要求咱們的方法調用,必須保持在必定的界限範圍以內,儘可能減小對象的依賴關係

3.8 其它原則

除了上面提到的這些原則,還有一些你們都熟知的原則,好比:

面向接口編程;

優先使用組合/聚合,而非繼承;

固然也還有不少不是很熟悉的原則,好比:

一個類須要的數據應該隱藏在類的內部;

類之間應該零耦合,或者只有傳導耦合,換句話說,類之間要麼沒有關係,要麼只使用另外一個類的接口提供的操做;

在水平方向上儘量統一的分佈系統功能;

4. 日誌規範

根據日誌的嚴重程度和功能所劃分紅如下五種:

  1. FETA:致命的錯誤,程序不能或不該該正常運行。FETAL級別的日誌主要用於記錄很是嚴重而致使程序不能正常運行的錯誤,好比得不到FileSystem對象、Job運行失敗、ODFS寫重要的數據文件不成功等。

  2. ERROR:嚴重的錯誤,但不影響程序流程,Tool能夠繼續運行。ERROR級別的日誌主要用於記錄雖然嚴重但不至於影響程序運行的錯誤,好比Parser解析失敗等。代碼中捕獲異常後輸出的日誌一部分會屬於ERROR級別。

  3. WARN: 警告日誌,不影響程序流程,Tool能夠繼續運行。WARN級別的日誌與ERROR級別的日誌有一些類似,但一般是不能準確判斷是否出現問題,須要人來判 斷,好比某輪待抓取的數據爲0;而ERROR級別的日誌一般是在程序運行過程當中就能夠發現代碼、流程或數據等的某一方面或幾方面存在問題。

  4. INFO:信息日誌,不影響程序流程,Tool能夠繼續運行。INFO級別的日誌主要用來記錄一些須要統計的信息,好比抓取統計,以及一些必要的諸如程序啓停等信息。

  5. DEBUG:調試日誌,不影響程序流程,Tool能夠繼續運行。DEBUG級別的日誌主要用於記錄調試所用到的信息,在線上運行的過程當中該級別的日誌不會輸出。

設計這些日誌級別是爲了方便的對日誌進行過濾,對於線上系統,通常會將日誌級別設置爲WARN,這是爲了讓維護人員可以根據日誌迅速判斷問題,另外一方面不會由於頻繁的寫磁盤也帶來性能問題。而在查找具體問題時,可能要將日誌級別調到DEBUG,但願經過更多的輸出信息來定位問題。

5. 日誌格式

日誌格式指的是輸出到日誌文件的每一條日誌所遵循的格式。爲方便起見,每一條日誌格式都由若干個「key=value」這樣的屬性對組成,不一樣的屬性對之間用製表符(即「\t」)分隔。有幾個特殊的屬性稍有區別,不採用「key=value」這樣的形式:

  1. 時間:時間是一條日誌的第一項。而因爲outlog會採用「yyyyMMddHHmmssSS」這樣的格式自動記錄日誌的時間,因此無需再增長「key=value」這種格式的時間。
  2. 級別:級別是一條日誌的第二項。級別採用「[LEVEL]」這種形式,如「[INFO]」。
  3. 消息體:消息體是一條日誌的最後一項。爲更直觀,消息體也不採用「key=value」的格式,而直接輸出,如「This is a message.」。

除此以外的其餘屬性均採用「key=value」的格式。這些屬性對位於級別和消息體之間,以製表符(即「\t」)分隔,無需排序。對於「key=value」中的「key」,有一些經常使用的值能夠定義爲常量,如「CLASS(類名)」、「ERROR(錯誤類型)」等,對於很是見或特殊需求的「key」,能夠在記log的時候本身定義,解析的時候注意保持一致便可。 屬性中還有一個特殊的屬性,即「ERROR(錯誤類型)」,用於表示錯誤的類型。ERROR和FETAL級別的日誌中須要包含該屬性,其餘級別的日誌中無需包括。「ERROR」屬性的取值會有一個固定的範圍,包括但不限於如下幾種:

  1. IOException
  2. ConnectionRefused
相關文章
相關標籤/搜索