一、 類(lèi)
類(lèi)通常由變量沃疮、屬性和方法組成盒让。按照書(shū)中所講的Java的約定,類(lèi)應(yīng)該由一組變量開(kāi)始司蔬,如果有靜態(tài)公共常量邑茄,應(yīng)該放在前面,然后是私有靜態(tài)變量和私有實(shí)體變量俊啼。公共函數(shù)跟在變量之后肺缕,一些供公共函數(shù)調(diào)用的私有工具函數(shù)在公共函數(shù)之后。
和函數(shù)一樣,類(lèi)也應(yīng)該要盡可能的短小同木。但和函數(shù)不同不是以代碼行數(shù)來(lái)權(quán)衡浮梢,而是以職責(zé)。如果無(wú)法準(zhǔn)確的為某個(gè)類(lèi)命名彤路,則有可能是該類(lèi)的職責(zé)過(guò)多秕硝。
單一職責(zé)原則(SRP):類(lèi)或模塊應(yīng)該有且只有一條加以修改的理由。
在實(shí)際的工作中很多開(kāi)發(fā)人員往往不會(huì)思考這么多洲尊,他們只想著讓代碼可以工作就可以了远豺,所以經(jīng)常出現(xiàn)幾千行的大類(lèi)。系統(tǒng)應(yīng)該是有許多短小的類(lèi)而不是少量巨大的類(lèi)組成坞嘀。每個(gè)小類(lèi)有單一的職責(zé)躯护,只有一個(gè)修改的原因,所有這些小類(lèi)在一起協(xié)同工作完成系統(tǒng)的功能丽涩。
- 高內(nèi)聚:如果一個(gè)類(lèi)中每個(gè)變量都被每個(gè)方法所使用棺滞,則該類(lèi)有最大的內(nèi)聚性。
高內(nèi)聚低耦合:提出與結(jié)構(gòu)化編程矢渊,內(nèi)聚表述模塊內(nèi)部功能不同操作邏輯之間的距離继准,如果一個(gè)類(lèi)的每個(gè)變量都被每個(gè)方法所使用為最大的內(nèi)聚;耦合描述模塊之間的依賴(lài)程度昆淡;高內(nèi)聚低耦合以簡(jiǎn)單的方式表述就是功能完備(高內(nèi)聚)對(duì)象之間是通過(guò)穩(wěn)定的接口(低耦合)交互的锰瘸。保持內(nèi)聚性得到許多短小的類(lèi)。
重構(gòu)函數(shù)也會(huì)促使類(lèi)職責(zé)的分離昂灵,看下面場(chǎng)景:
將一個(gè)有許多變量的大函數(shù)拆分成小函數(shù),如果拆出來(lái)的代碼使用了其中4個(gè)變量舞萄,那么就會(huì)將這4個(gè)變量作為參數(shù)傳入到小函數(shù)中眨补,如果使用的變量越多,就意味著小函數(shù)的參數(shù)越多倒脓,這時(shí)可以講這4個(gè)變量升級(jí)成實(shí)體變量撑螺,小函數(shù)就不需要參數(shù)了,可以直接使用這些變量崎弃。這樣就使內(nèi)聚性變低甘晤,因?yàn)轭?lèi)中有很多的變量只為少數(shù)的函數(shù)服務(wù),這時(shí)就可以將這些變量和函數(shù)拆分出來(lái)饲做,單獨(dú)成類(lèi)线婚。
- 開(kāi)放閉合原則(OCP)
類(lèi)應(yīng)當(dāng)對(duì)擴(kuò)展開(kāi)放,對(duì)修改封閉盆均。我們可以借助接口和抽象類(lèi)來(lái)隔離這些細(xì)節(jié)帶來(lái)的影響塞弊。
- 依賴(lài)倒置原則(DIP)
描述組件之間高層組件不應(yīng)該依賴(lài)于底層組件。依賴(lài)倒置是指實(shí)現(xiàn)和接口倒置,采用自頂向下的方式關(guān)注所需的底層組件接口游沿,而不是其實(shí)現(xiàn)饰抒。DI模式很好的就是應(yīng)用IOC(控制反轉(zhuǎn))框架,構(gòu)造方式分為構(gòu)造注入诀黍,函數(shù)注入袋坑,屬性注入。
小結(jié):
- 類(lèi)第一原則應(yīng)是是小并足夠的小眯勾。
- 單一原則(SRP)
- 內(nèi)聚
- 依賴(lài)倒置(DIP)
- 開(kāi)放閉合原則(OCP)
二枣宫、 注釋
注釋是一把雙刃劍,好的注釋能夠給我們好的指導(dǎo)咒精,不好的注釋只會(huì)將我們誤導(dǎo)镶柱。注釋是彌補(bǔ)代碼子表述不足的一種手段,就像設(shè)計(jì)模式是用來(lái)彌補(bǔ)語(yǔ)言不足一樣模叙。
代碼是我們獲取信息的準(zhǔn)確來(lái)源歇拆,注釋隨著項(xiàng)目人員的更替,反復(fù)的修改最終可能詞不達(dá)意了范咨,因?yàn)楹芏嚅_(kāi)發(fā)人員在整合代碼故觅,修改方法的時(shí)候并不是總是同步修改注釋。
有時(shí)候看到一個(gè)函數(shù)的代碼寫(xiě)的很糟糕渠啊,邏輯很混亂输吏,有開(kāi)發(fā)人員可能想,給這個(gè)函數(shù)加上幾行注釋?zhuān)@樣有可能起到適得其反的作用替蛉,這時(shí)要做的是將函數(shù)整理干凈贯溅。
代碼即注釋?zhuān)芏鄷?shū)和大師都這么講,意思是我們要用代碼本身來(lái)解釋我們的意圖躲查,那就要求我們要控制好函數(shù)只做一件事它浅,函數(shù)名和變量名要規(guī)范和可讀。
當(dāng)然也不是所有的注釋都沒(méi)有用镣煮,像下面幾種類(lèi)型的注釋是有必要的:
具有警示性的注釋?zhuān)?br>
描述一些負(fù)責(zé)業(yè)務(wù)場(chǎng)景姐霍;
有些函數(shù)現(xiàn)在還是一個(gè)空殼,但在將來(lái)可能有用典唇,有必要寫(xiě)镊折。
當(dāng)我們不得不寫(xiě)一些注釋的時(shí)候,要確保言簡(jiǎn)意賅介衔,能夠很好的表達(dá)意思恨胚,不要造成誤解,也不要寫(xiě)多余的廢話夜牡。
還有一種注釋被稱(chēng)為日志式注釋?zhuān)话愠霈F(xiàn)在一個(gè)類(lèi)的開(kāi)始部分与纽,記錄每次修改時(shí)的時(shí)間侣签、人員名稱(chēng)和修改內(nèi)容。隨著時(shí)間的推移這類(lèi)注釋會(huì)變得非常冗長(zhǎng)急迂。這類(lèi)注釋在一些項(xiàng)目中很普遍影所,而且有時(shí)會(huì)被嚴(yán)格要求寫(xiě),但書(shū)中強(qiáng)調(diào)現(xiàn)在的源代碼都會(huì)有源代碼工具來(lái)進(jìn)行管理僚碎,修改記錄在源代碼工具中有保存猴娩,這種日志式的注釋?xiě)?yīng)該全部刪除。
項(xiàng)目代碼中經(jīng)常會(huì)出現(xiàn)被注釋掉的代碼勺阐,這對(duì)后面的維護(hù)人員會(huì)造成困擾卷中,也會(huì)使代碼變得混亂,這種代碼同樣可以刪掉渊抽,因?yàn)槲覀冇性创a管理工具蟆豫。
對(duì)于書(shū)上的這段描述傳結(jié)合親身經(jīng)歷產(chǎn)生了異議,和大家討論一下懒闷。
經(jīng)歷1:
Merge十减。
很多公司都會(huì)為新的feature,或fix defect而開(kāi)辟新的分支愤估,而當(dāng)分支合并時(shí)原始分支的歷史版本帮辟,可能將會(huì)丟失。
經(jīng)歷2:
根據(jù)重構(gòu)的需要玩焰,有些模塊需要搬遷到新的文件中由驹,有些文件需要新命名/重命名。
而在有些版本控制工具中昔园,如SVN蔓榄,重命名一個(gè)文件,它是當(dāng)作刪除然后添加過(guò)來(lái)處理的默刚。這樣一來(lái)润樱,新的文件將會(huì)有新的歷史,而原來(lái)的歷史羡棵,已隨老的文件煙消云散。
也許嗅钻,從版本控制中還能找回被刪除的老的文件皂冰。但如果作為一個(gè)新接觸的員工,對(duì)于將重命名分解為刪除和添加的操作而言养篓,誰(shuí)又知道以前被刪除的文件是哪一個(gè)秃流?時(shí)間長(zhǎng)了,老員工也記不住傲舶胀!
總結(jié):
對(duì)于以后有影響的或者增強(qiáng)性能比對(duì)的注釋?zhuān)?qǐng)不要?jiǎng)h除概说。除非確定以后真的不再需要。因?yàn)橄ィ姹究刂乒ぞ咛桥猓鋵?shí)并不能滿(mǎn)足我們所想象的需求。