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;編程
Class類:類名必須是名詞,且以大寫字母開頭。類名應該簡單清晰。緩存
Interface類: 3.1 Interface命名上,暫定以XxxService的形式提供; 3.2 最終提供的接口應以Java Interface的形式出現; 3.3 每一個獨立的業務的Interface應該有獨立的package包,一個package下可包含該業務模塊下的多個Interface; 3.4 每一個Interface的一個方法對應所謂的一個「中間層服務接口」,須要按照規範書寫該接口的說明;工具
緩存命名規則:對緩存的key要採用命名空間,以免衝突,同時要考慮緩存的命中率,不要浪費緩存的空間。性能
業務模塊的開發過程當中,應該避免過長的方法,進行合理的功能模塊的提取以及抽象,避免同一段代碼、相似代碼處處copy的狀況。單元測試
所謂單一職責原則,指的就是:一個類應該僅有一個引發它變化的緣由。測試
這裏變化的緣由就是 所說的「職責」,若是一個類有多個引發它變化的緣由,那麼也就意味着這個類有多個職責,再進一步說,就是把多個職責耦合在一塊兒了
。這會形成職責的相互影響,可能一個職責的變化,會影響到其它職責的實現,甚至引發其它職責跟着變化,這種設計是很脆弱的。編碼
這個原則看起來是最簡單和最好理解的,可是其實是很難徹底作到的,難點在於如何區分這個「職責」
,這是個沒有標準量化的東西,哪些算職責,到底這個職責有多大的粒度,這個職責如何細化等等。所以,在實際開發中,這個原則也是最容易違反的。設計
所謂開放-關閉原則,指的就是:一個類應該對擴展開放,對修改關閉。通常也被簡稱爲開閉原則,開閉原則是設計中很是核心的一個原則。調試
開閉原則要求的是,類的行爲是能夠擴展的
,並且是在不修改已有的代碼的狀況下進行擴展,也沒必要改動已有的源代碼或者二進制代碼。日誌
看起來好像是矛盾的,怎麼樣才能實現呢?
實現開閉原則的關鍵就在於合理的抽象,分離出變化與不變化的部分,爲變化的部分預留下可擴展的方式
,好比:鉤子方法、或是動態組合對象等等。
這個原則看起來也很簡單,但事實上,一個系統要所有作到遵照開閉原則,幾乎是不可能的
,也沒這個必要。適度的抽象能夠提升系統的靈活性,使其可擴展、可維護,可是過分的抽象,會大大增長系統的複雜程度
。應該在須要改變的地方應用開閉原則就能夠了,而不用處處使用,從而陷入過分設計。
所謂里氏替換原則,指的就是:子類型必須可以替換掉它們的父類型。這很明顯是一種多態的使用狀況,它能夠避免在多態的應用中,出現某些隱蔽的錯誤。
事實上,當一個類繼承了另一個類,那麼子類就擁有了父類中能夠繼承下來的屬性和操做,理論上來講,此時使用子類型去替換掉父類型,應該不會引發原來使用父類型的程序出現錯誤。
可是,很不幸的是,在某些狀況下是會出現問題的,好比:若是子類型覆蓋了父類型的某些方法,或者是子類型修改了父類型某些屬性的值,那麼原來使用父類型的程序就可能會出現錯誤
,由於在運行期間,從表面上看,它調用的是父類型的方法,須要的是父類型方法實現的功能,可是實際運行調用的確是子類型覆蓋實現的方法,而該方法跟父類型的方法並不同,那就會致使錯誤的產生
。
從另一個角度來講,里氏替換原則是實現開閉的主要原則之一,開閉原則要求對擴展開放,擴展的一個實現手段就是使用繼承,而里氏替換原則是保證子類型可以正確替換父類型,只有能正確替換,才能實現擴展,不然擴展了也會出現錯誤
。
所謂依賴倒置原則,指的就是:
要依賴於抽象,不要依賴於具體類
。要作到依賴倒置,典型的應該作到:
高層模塊不該該依賴於底層模塊
,兩者都應該依賴於抽象;抽象不該該依賴於具體實現
,具體實現應該依賴於抽象;
不少人以爲,層次化調用的時候,應該是高層調用「底層所擁有的接口」,這是一種典型的誤解。事實上,通常高層模塊包含對業務功能的處理和業務策略選擇,應該被重用,應該是高層模塊去影響底層的具體實現。
所以,這個底層的接口,應該是由高層提出的,而後由底層實現的,也就是說底層的接口的全部權在高層模塊
,所以是一種全部權的倒置。
倒置接口全部權,這就是著名的Hollywood(好萊塢)原則:不要找咱們,咱們會聯繫你。
所謂接口隔離原則,指的就是:
不該該強迫客戶依賴於他們不用的方法
。
這個原則用來處理那些比較「龐大」的接口,這種接口一般會有較多的操做聲明,涉及到不少的職責。客戶在使用這樣的接口的時候,一般會有不少它不須要的方法,這些方法對於客戶來說,就是一種接口污染,至關於強迫用戶在一大堆「垃圾方法」裏面去尋找他須要的方法。
所以,這樣的接口應該被分離,應該按照不一樣的客戶須要來分離成爲針對客戶的接口,這樣的接口裏面,只包含客戶須要的操做聲明,這樣既方便了客戶的使用,也能夠避免因誤用接口而致使的錯誤。
分離接口的方式,除了直接進行代碼分離以外,還可使用委託來分離接口,在可以支持多重繼承的語言裏面,還能夠採用多重繼承的方式進行分離。
所謂最少知識原則,指的就是:
只和你的朋友談話
。
這個原則用來指導咱們在設計系統的時候,應該儘可能減小對象之間的交互,對象只和本身的朋友談話,也就是隻和本身的朋友交互,從而鬆散類之間的耦合
。經過鬆散類之間的耦合來下降類之間的相互依賴,這樣在修改系統的某一個部分時候,就不會影響其它的部分,從而使得系統具備更好的可維護性。
那麼究竟哪些對象才能被看成朋友呢?最少知識原則提供了一些指導:
當前對象自己;
經過方法的參數傳遞進來的對象;
當前對象所建立的對象;
當前對象的實例變量所引用的對象;
方法內所建立或實例化的對象;
總之,最少知識原則要求咱們的方法調用,必須保持在必定的界限範圍以內,儘可能減小對象的依賴關係。
除了上面提到的這些原則,還有一些你們都熟知的原則,好比:
面向接口編程;
優先使用組合/聚合,而非繼承;
固然也還有不少不是很熟悉的原則,好比:
一個類須要的數據應該隱藏在類的內部;
類之間應該零耦合,或者只有傳導耦合,換句話說,類之間要麼沒有關係,要麼只使用另外一個類的接口提供的操做;
在水平方向上儘量統一的分佈系統功能;
根據日誌的嚴重程度和功能所劃分紅如下五種:
FETA:致命的錯誤,程序不能或不該該正常運行。FETAL級別的日誌主要用於記錄很是嚴重而致使程序不能正常運行的錯誤,好比得不到FileSystem對象、Job運行失敗、ODFS寫重要的數據文件不成功等。
ERROR:嚴重的錯誤,但不影響程序流程,Tool能夠繼續運行。ERROR級別的日誌主要用於記錄雖然嚴重但不至於影響程序運行的錯誤,好比Parser解析失敗等。代碼中捕獲異常後輸出的日誌一部分會屬於ERROR級別。
WARN: 警告日誌,不影響程序流程,Tool能夠繼續運行。WARN級別的日誌與ERROR級別的日誌有一些類似,但一般是不能準確判斷是否出現問題,須要人來判 斷,好比某輪待抓取的數據爲0;而ERROR級別的日誌一般是在程序運行過程當中就能夠發現代碼、流程或數據等的某一方面或幾方面存在問題。
INFO:信息日誌,不影響程序流程,Tool能夠繼續運行。INFO級別的日誌主要用來記錄一些須要統計的信息,好比抓取統計,以及一些必要的諸如程序啓停等信息。
DEBUG:調試日誌,不影響程序流程,Tool能夠繼續運行。DEBUG級別的日誌主要用於記錄調試所用到的信息,在線上運行的過程當中該級別的日誌不會輸出。
設計這些日誌級別是爲了方便的對日誌進行過濾,對於線上系統,通常會將日誌級別設置爲WARN
,這是爲了讓維護人員可以根據日誌迅速判斷問題,另外一方面不會由於頻繁的寫磁盤也帶來性能問題。而在查找具體問題時,可能要將日誌級別調到DEBUG
,但願經過更多的輸出信息來定位問題。
日誌格式指的是輸出到日誌文件的每一條日誌所遵循的格式。爲方便起見,每一條日誌格式都由若干個「key=value」這樣的屬性對組成,不一樣的屬性對之間用製表符(即「\t」)分隔。有幾個特殊的屬性稍有區別,不採用「key=value」這樣的形式:
除此以外的其餘屬性均採用「key=value」的格式。這些屬性對位於級別和消息體之間,以製表符(即「\t」)分隔,無需排序。對於「key=value」中的「key」,有一些經常使用的值能夠定義爲常量,如「CLASS(類名)」、「ERROR(錯誤類型)」等,對於很是見或特殊需求的「key」,能夠在記log的時候本身定義,解析的時候注意保持一致便可。 屬性中還有一個特殊的屬性,即「ERROR(錯誤類型)」,用於表示錯誤的類型。ERROR和FETAL級別的日誌中須要包含該屬性,其餘級別的日誌中無需包括。「ERROR」屬性的取值會有一個固定的範圍,包括但不限於如下幾種:
- IOException
- ConnectionRefused