1. 分支開發(fā)流程
GIT分支開發(fā)規(guī)范负拟,具體請(qǐng)參考:http://www.reibang.com/p/cbd8cf5e232d溢陪。
2. 代碼規(guī)范
主要使用Java語(yǔ)言來(lái)進(jìn)行開發(fā)丰滑,嚴(yán)格遵循Sun公司的Java編碼規(guī)范。此外還有以下補(bǔ)充真屯。
2.1 大小寫
常量的字母全部大寫誊役,單詞之間用一個(gè)下劃線字符(_)進(jìn)行分隔。
除常量外的命名采用大小寫混合逗爹,提高名字的可讀性亡嫌。
一般采用小寫字母,但是類和接口的名字的首字母掘而,以及任何中間單詞的首字母應(yīng)該大寫挟冠。
2.2 編碼格式
確保IDE工作環(huán)境使用UTF-8編碼格式。
縮進(jìn)一律使用空格而非Tab镣屹。
縮進(jìn)一律采用4空格圃郊。可以設(shè)置IDE 1Tab=4空格女蜈。
對(duì)于非第一次創(chuàng)建的代碼文件持舆,禁止做reformate操作色瘩,這個(gè)操作會(huì)破壞代碼的修改歷史,造成大概率的push逸寓、merge居兆、pull等操作沖突。
2.3 常量定義
對(duì)具有特殊意義的數(shù)字或字符要以常量的形式定義竹伸,并說(shuō)明常量所表示的意義泥栖,避免幻數(shù)的出現(xiàn)。
2.4 統(tǒng)一定義公共常量
對(duì)于一些公共常量的使用勋篓,應(yīng)該單獨(dú)定義相應(yīng)的常量類吧享,并統(tǒng)一使用,避免在各業(yè)務(wù)類譬嚣、功能類中分別定義钢颂、直接使用。
2.5 命名規(guī)則
package:
1.1 package:每一個(gè)包的名稱總是小寫拜银,暫定將com.keegoo.+(模塊名)作為總前綴殊鞭,比如com.keegoo.demo.blog.service、com.keegoo.demo.blog.dto尼桶;
1.2明確不同業(yè)務(wù)建議建立子package操灿,比如有關(guān)User業(yè)務(wù)的:com.keegoo.user.account.service、com.keegoo.user.account.dto泵督;
class類:類名必須是名詞趾盐,且以大寫字母開頭。類名應(yīng)該簡(jiǎn)單清晰小腊。
interface類:
3.1 Interface命名上谤碳,暫定以XxxService的形式提供;
3.2 最終提供的接口應(yīng)以Java Interface的形式出現(xiàn)溢豆;
3.3 每個(gè)獨(dú)立的業(yè)務(wù)的Interface應(yīng)該有獨(dú)立的package包蜒简,一個(gè)package下可包含該業(yè)務(wù)模塊下的多個(gè)Interface;
3.4 每個(gè)Interface的一個(gè)方法對(duì)應(yīng)所謂的一個(gè)“中間層服務(wù)接口”漩仙,需要按照規(guī)范書寫該接口的說(shuō)明搓茬;
緩存命名規(guī)則:對(duì)緩存的key要采用命名空間,以避免沖突队他,同時(shí)要考慮緩存的命中率卷仑,不要浪費(fèi)緩存的空間。
2.6 controller麸折,interface類锡凝,接口實(shí)現(xiàn)類編寫注意事項(xiàng)
controller類里不能出現(xiàn)業(yè)務(wù)邏輯,只能直接調(diào)用Service類垢啼,不能直接調(diào)用Biz類(Biz類是對(duì)業(yè)務(wù)邏輯的實(shí)現(xiàn)封裝窜锯,不依賴dao層张肾,可獨(dú)立做單元測(cè)試),manager類則是作為service锚扎、biz吞瞪、dao三層的粘合劑,來(lái)協(xié)調(diào)三者執(zhí)行關(guān)系驾孔。
interface接口定義類只定義方法芍秆,方法的實(shí)現(xiàn)要在實(shí)現(xiàn)類里完成,interface接口以xxxService結(jié)尾翠勉,接口實(shí)現(xiàn)類以xxxServiceImpl結(jié)尾妖啥。
2.7 注釋
方法注釋:每個(gè)接口、方法應(yīng)該有一個(gè)方法的整體說(shuō)明对碌,包括方法實(shí)現(xiàn)的功能迹栓、參數(shù)的詳細(xì)含義、返回值的取值及其詳細(xì)含義俭缓。
類注釋:對(duì)于工具類或者流程類,需要在類的注釋中對(duì)于類的功能進(jìn)行詳細(xì)的說(shuō)明酥郭;對(duì)于Model類华坦,要對(duì)其重要的屬性添加注釋,注明其含義不从,必要時(shí)要重載hashCode和equals惜姐,toString方法。
3. 設(shè)計(jì)規(guī)范
3.1 對(duì)功能性模塊的抽象
業(yè)務(wù)模塊的開發(fā)過程中椿息,應(yīng)該避免過長(zhǎng)的方法歹袁,進(jìn)行合理的功能模塊的提取以及抽象,避免同一段代碼寝优、類似代碼到處copy的情況条舔。
3.2 單一職責(zé)原則SRP(Single Responsibility Principle)
所謂單一職責(zé)原則,指的就是:一個(gè)類應(yīng)該僅有一個(gè)引起它變化的原因乏矾。
這里變化的原因就是所說(shuō)的“職責(zé)”孟抗,如果一個(gè)類有多個(gè)引起它變化的原因,那么也就意味著這個(gè)類有多個(gè)職責(zé)钻心,再進(jìn)一步說(shuō)凄硼,就是把多個(gè)職責(zé)耦合在一起了。這會(huì)造成職責(zé)的相互影響捷沸,可能一個(gè)職責(zé)的變化摊沉,會(huì)影響到其它職責(zé)的實(shí)現(xiàn),甚至引起其它職責(zé)跟著變化痒给,這種設(shè)計(jì)是很脆弱的说墨。
這個(gè)原則看起來(lái)是最簡(jiǎn)單和最好理解的骏全,但是實(shí)際上是很難完全做到的,難點(diǎn)在于如何區(qū)分這個(gè)“職責(zé)”婉刀,這是個(gè)沒有標(biāo)準(zhǔn)量化的東西吟温,哪些算職責(zé),到底這個(gè)職責(zé)有多大的粒度突颊,這個(gè)職責(zé)如何細(xì)化等等鲁豪。因此,在實(shí)際開發(fā)中律秃,這個(gè)原則也是最容易違反的爬橡。
3.3 開放-關(guān)閉原則OCP(Open-Closed Principle)
所謂開放-關(guān)閉原則,指的就是:一個(gè)類應(yīng)該對(duì)擴(kuò)展開放棒动,對(duì)修改關(guān)閉糙申。一般也被簡(jiǎn)稱為開閉原則,開閉原則是設(shè)計(jì)中非常核心的一個(gè)原則船惨。
開閉原則要求的是柜裸,類的行為是可以擴(kuò)展的,而且是在不修改已有的代碼的情況下進(jìn)行擴(kuò)展粱锐,也不必改動(dòng)已有的源代碼或者二進(jìn)制代碼疙挺。
看起來(lái)好像是矛盾的,怎么樣才能實(shí)現(xiàn)呢怜浅?
實(shí)現(xiàn)開閉原則的關(guān)鍵就在于合理的抽象拳亿,分離出變化與不變化的部分耻蛇,為變化的部分預(yù)留下可擴(kuò)展的方式绣版,比如:鉤子方法蚂四、或是動(dòng)態(tài)組合對(duì)象等等。
這個(gè)原則看起來(lái)也很簡(jiǎn)單跨琳,但事實(shí)上自点,一個(gè)系統(tǒng)要全部做到遵守開閉原則,幾乎是不可能的脉让,也沒這個(gè)必要樟氢。適度的抽象可以提高系統(tǒng)的靈活性,使其可擴(kuò)展侠鳄、可維護(hù)埠啃,但是過度的抽象,會(huì)大大增加系統(tǒng)的復(fù)雜程度伟恶。應(yīng)該在需要改變的地方應(yīng)用開閉原則就可以了碴开,而不用到處使用,從而陷入過度設(shè)計(jì)。
3.4 里氏替換原則LSP(Liskov Substitution Principle)
所謂里氏替換原則潦牛,指的就是:子類型必須能夠替換掉它們的父類型眶掌。這很明顯是一種多態(tài)的使用情況,它可以避免在多態(tài)的應(yīng)用中巴碗,出現(xiàn)某些隱蔽的錯(cuò)誤朴爬。
事實(shí)上,當(dāng)一個(gè)類繼承了另外一個(gè)類橡淆,那么子類就擁有了父類中可以繼承下來(lái)的屬性和操作召噩,理論上來(lái)說(shuō),此時(shí)使用子類型去替換掉父類型逸爵,應(yīng)該不會(huì)引起原來(lái)使用父類型的程序出現(xiàn)錯(cuò)誤具滴。
但是,很不幸的是师倔,在某些情況下是會(huì)出現(xiàn)問題的构韵,比如:如果子類型覆蓋了父類型的某些方法,或者是子類型修改了父類型某些屬性的值趋艘,那么原來(lái)使用父類型的程序就可能會(huì)出現(xiàn)錯(cuò)誤疲恢,因?yàn)樵谶\(yùn)行期間,從表面上看瓷胧,它調(diào)用的是父類型的方法显拳,需要的是父類型方法實(shí)現(xiàn)的功能,但是實(shí)際運(yùn)行調(diào)用的確是子類型覆蓋實(shí)現(xiàn)的方法抖单,而該方法跟父類型的方法并不一樣,那就會(huì)導(dǎo)致錯(cuò)誤的產(chǎn)生遇八。
從另外一個(gè)角度來(lái)說(shuō)矛绘,里氏替換原則是實(shí)現(xiàn)開閉的主要原則之一,開閉原則要求對(duì)擴(kuò)展開放刃永,擴(kuò)展的一個(gè)實(shí)現(xiàn)手段就是使用繼承货矮,而里氏替換原則是保證子類型能夠正確替換父類型,只有能正確替換斯够,才能實(shí)現(xiàn)擴(kuò)展囚玫,否則擴(kuò)展了也會(huì)出現(xiàn)錯(cuò)誤。
3.5 依賴倒置原則DIP(Dependence Inversion Principle)
所謂依賴倒置原則读规,指的就是:要依賴于抽象抓督,不要依賴于具體類。要做到依賴倒置束亏,典型的應(yīng)該做到:
高層模塊不應(yīng)該依賴于底層模塊铃在,二者都應(yīng)該依賴于抽象;
抽象不應(yīng)該依賴于具體實(shí)現(xiàn),具體實(shí)現(xiàn)應(yīng)該依賴于抽象定铜;
很多人覺得阳液,層次化調(diào)用的時(shí)候,應(yīng)該是高層調(diào)用“底層所擁有的接口”揣炕,這是一種典型的誤解帘皿。事實(shí)上,一般高層模塊包含對(duì)業(yè)務(wù)功能的處理和業(yè)務(wù)策略選擇畸陡,應(yīng)該被重用鹰溜,應(yīng)該是高層模塊去影響底層的具體實(shí)現(xiàn)。
因此罩锐,這個(gè)底層的接口奉狈,應(yīng)該是由高層提出的,然后由底層實(shí)現(xiàn)的涩惑,也就是說(shuō)底層的接口的所有權(quán)在高層模塊仁期,因此是一種所有權(quán)的倒置。
倒置接口所有權(quán)竭恬,這就是著名的Hollywood(好萊塢)原則:不要找我們跛蛋,我們會(huì)聯(lián)系你。
3.6 接口隔離原則ISP(Interface Segregation Principle)
所謂接口隔離原則痊硕,指的就是:不應(yīng)該強(qiáng)迫客戶依賴于他們不用的方法赊级。
這個(gè)原則用來(lái)處理那些比較“龐大”的接口,這種接口通常會(huì)有較多的操作聲明岔绸,涉及到很多的職責(zé)理逊。客戶在使用這樣的接口的時(shí)候盒揉,通常會(huì)有很多它不需要的方法晋被,這些方法對(duì)于客戶來(lái)講,就是一種接口污染刚盈,相當(dāng)于強(qiáng)迫用戶在一大堆“垃圾方法”里面去尋找他需要的方法羡洛。
因此,這樣的接口應(yīng)該被分離藕漱,應(yīng)該按照不同的客戶需要來(lái)分離成為針對(duì)客戶的接口欲侮,這樣的接口里面,只包含客戶需要的操作聲明肋联,這樣既方便了客戶的使用威蕉,也可以避免因誤用接口而導(dǎo)致的錯(cuò)誤。
分離接口的方式橄仍,除了直接進(jìn)行代碼分離之外忘伞,還可以使用委托來(lái)分離接口,在能夠支持多重繼承的語(yǔ)言里面,還可以采用多重繼承的方式進(jìn)行分離氓奈。
3.7 最少知識(shí)原則(Least Knowledge Principle)
所謂最少知識(shí)原則翘魄,指的就是:只和你的朋友談話。
這個(gè)原則用來(lái)指導(dǎo)我們?cè)谠O(shè)計(jì)系統(tǒng)的時(shí)候舀奶,應(yīng)該盡量減少對(duì)象之間的交互暑竟,對(duì)象只和自己的朋友談話,也就是只和自己的朋友交互育勺,從而松散類之間的耦合但荤。通過松散類之間的耦合來(lái)降低類之間的相互依賴,這樣在修改系統(tǒng)的某一個(gè)部分時(shí)候涧至,就不會(huì)影響其它的部分腹躁,從而使得系統(tǒng)具有更好的可維護(hù)性。
那么究竟哪些對(duì)象才能被當(dāng)作朋友呢南蓬?最少知識(shí)原則提供了一些指導(dǎo):
當(dāng)前對(duì)象本身纺非;
通過方法的參數(shù)傳遞進(jìn)來(lái)的對(duì)象;
當(dāng)前對(duì)象所創(chuàng)建的對(duì)象赘方;
當(dāng)前對(duì)象的實(shí)例變量所引用的對(duì)象烧颖;
方法內(nèi)所創(chuàng)建或?qū)嵗膶?duì)象;
總之窄陡,最少知識(shí)原則要求我們的方法調(diào)用炕淮,必須保持在一定的界限范圍之內(nèi),盡量減少對(duì)象的依賴關(guān)系跳夭。
3.8 其它原則
除了上面提到的這些原則涂圆,還有一些大家都熟知的原則,比如:
面向接口編程币叹;
優(yōu)先使用組合/聚合润歉,而非繼承;
當(dāng)然也還有很多不是很熟悉的原則套硼,比如:
一個(gè)類需要的數(shù)據(jù)應(yīng)該隱藏在類的內(nèi)部卡辰;
類之間應(yīng)該零耦合胞皱,或者只有傳導(dǎo)耦合邪意,換句話說(shuō),類之間要么沒有關(guān)系反砌,要么只使用另一個(gè)類的接口提供的操作雾鬼;
在水平方向上盡可能統(tǒng)一的分布系統(tǒng)功能;
4. 日志規(guī)范
根據(jù)日志的嚴(yán)重程度和功能所劃分成以下五種:
FETA:致命的錯(cuò)誤宴树,程序不能或不應(yīng)該正常運(yùn)行策菜。FETAL級(jí)別的日志主要用于記錄非常嚴(yán)重而導(dǎo)致程序不能正常運(yùn)行的錯(cuò)誤,比如得不到FileSystem對(duì)象、Job運(yùn)行失敗又憨、ODFS寫重要的數(shù)據(jù)文件不成功等翠霍。
ERROR:嚴(yán)重的錯(cuò)誤,但不影響程序流程蠢莺,Tool可以繼續(xù)運(yùn)行寒匙。ERROR級(jí)別的日志主要用于記錄雖然嚴(yán)重但不至于影響程序運(yùn)行的錯(cuò)誤,比如Parser解析失敗等躏将。代碼中捕獲異常后輸出的日志一部分會(huì)屬于ERROR級(jí)別锄弱。
WARN: 警告日志,不影響程序流程祸憋,Tool可以繼續(xù)運(yùn)行会宪。WARN級(jí)別的日志與ERROR級(jí)別的日志有一些相似,但通常是不能準(zhǔn)確判斷是否出現(xiàn)問題蚯窥,需要人來(lái)判 斷掸鹅,比如某輪待抓取的數(shù)據(jù)為0;而ERROR級(jí)別的日志通常是在程序運(yùn)行過程中就可以發(fā)現(xiàn)代碼沟沙、流程或數(shù)據(jù)等的某一方面或幾方面存在問題河劝。
INFO:信息日志,不影響程序流程矛紫,Tool可以繼續(xù)運(yùn)行赎瞎。INFO級(jí)別的日志主要用來(lái)記錄一些需要統(tǒng)計(jì)的信息,比如抓取統(tǒng)計(jì)颊咬,以及一些必要的諸如程序啟停等信息务甥。
DEBUG:調(diào)試日志,不影響程序流程喳篇,Tool可以繼續(xù)運(yùn)行敞临。DEBUG級(jí)別的日志主要用于記錄調(diào)試所用到的信息,在線上運(yùn)行的過程中該級(jí)別的日志不會(huì)輸出麸澜。
設(shè)計(jì)這些日志級(jí)別是為了方便的對(duì)日志進(jìn)行過濾挺尿,對(duì)于線上系統(tǒng),一般會(huì)將日志級(jí)別設(shè)置為WARN炊邦,這是為了讓維護(hù)人員能夠根據(jù)日志迅速判斷問題编矾,另一方面不會(huì)因?yàn)轭l繁的寫磁盤也帶來(lái)性能問題。而在查找具體問題時(shí)馁害,可能要將日志級(jí)別調(diào)到DEBUG窄俏,希望通過更多的輸出信息來(lái)定位問題。
5. 日志格式
日志格式指的是輸出到日志文件的每一條日志所遵循的格式碘菜。為方便起見凹蜈,每一條日志格式都由若干個(gè)“key=value”這樣的屬性對(duì)組成限寞,不同的屬性對(duì)之間用制表符(即“\t”)分隔。有幾個(gè)特殊的屬性稍有區(qū)別仰坦,不采用“key=value”這樣的形式:
時(shí)間:時(shí)間是一條日志的第一項(xiàng)履植。而由于outlog會(huì)采用“yyyyMMddHHmmssSS”這樣的格式自動(dòng)記錄日志的時(shí)間,所以無(wú)需再增加“key=value”這種格式的時(shí)間悄晃。
級(jí)別:級(jí)別是一條日志的第二項(xiàng)静尼。級(jí)別采用“[LEVEL]”這種形式,如“[INFO]”传泊。
消息體:消息體是一條日志的最后一項(xiàng)鼠渺。為更直觀,消息體也不采用“key=value”的格式眷细,而直接輸出拦盹,如“This is a message.”。
除此之外的其他屬性均采用“key=value”的格式溪椎。這些屬性對(duì)位于級(jí)別和消息體之間普舆,以制表符(即“\t”)分隔,無(wú)需排序校读。對(duì)于“key=value”中的“key”沼侣,有一些常用的值可以定義為常量,如“CLASS(類名)”歉秫、“ERROR(錯(cuò)誤類型)”等蛾洛,對(duì)于非常見或特殊需求的“key”,可以在記log的時(shí)候自己定義雁芙,解析的時(shí)候注意保持一致即可轧膘。 屬性中還有一個(gè)特殊的屬性,即“ERROR(錯(cuò)誤類型)”兔甘,用于表示錯(cuò)誤的類型谎碍。ERROR和FETAL級(jí)別的日志中需要包含該屬性,其他級(jí)別的日志中無(wú)需包括洞焙◇〉恚“ERROR”屬性的取值會(huì)有一個(gè)固定的范圍,包括但不限于以下幾種:
IOException
ConnectionRefused
鏈接:http://www.reibang.com/p/93e3d991756b