最近感覺自己老了,一直呆在小公司,感覺到了疲憊與苦澀,雖然并沒有如老板所想已達(dá)到瓶頸,依然感覺還有好多東西可學(xué)和想學(xué),不過我的前面的確是有一堵無形的墻在擋住我前行的腳步,我希望自己能夠停下來,靜下心來,對自己的以往的工作進(jìn)行總結(jié)和反思, 所以期望寫一系列的文章來總結(jié)總結(jié)自己的經(jīng)驗,反思自己,希望在反思中有進(jìn)一步的提高!!
這一篇總結(jié)一位老碼農(nóng)幾年編碼的所思所想所感, 講述代碼規(guī)范的同時也解釋為啥要這么干
-
為什么要有代碼規(guī)范
代碼規(guī)范的目的是"讀",給N久之后的自己, 給其他人讀, 試想過了半年之后,你再看代碼, 你是否能很快就看懂自己曾經(jīng)寫過的程序呢?我覺得維護(hù)過別人寫的代碼的人都能明白這個問題.
-
陷阱和錯誤
- 使用前綴
比如項目名稱叫做TaoBao,則前綴為TB, 前綴的意義在于避免沖突,特別是與第三方代碼的沖突,以前經(jīng)常碰到這種坑,某些惡心的第三方庫竟然前綴都不加就滿世界的發(fā)布,特別是一些基礎(chǔ)類,如Base64.h
- 條件陷阱
這個藏得有些深,經(jīng)常會犯錯,具體如
<pre>if (v1 = 1) { // 判斷V1是否等于1 }
</pre>這段代碼本意是判斷v1是否等于1,結(jié)果v1被賦值為1了,并且因為賦值得到的結(jié)果是True,所以if 代碼塊也會被執(zhí)行
針對這種情況,一般判斷采用反寫,如下代碼,如果寫錯,立馬報錯就可以改過來了
<pre>if (1 = v1) { // 判斷V1是否等于1,錯誤會立即報錯 }
</pre> - 魔法數(shù)字
這個也是挺惡心的, 經(jīng)常會碰到這樣的代碼
<pre>int result = v1 + 7788
</pre>從始至終沒有解釋下7788是什么? 這就是魔法數(shù)字, 為了避免這種情況, 將某些常量命名,
<pre>#define TBBeginTagOfCovers 7788 int result = v1 + TBBeginTagOfCovers
</pre>
-
怎樣讓代碼整潔
-
類命名
- 類名具有意義,能夠一眼就知道干嘛的
- 首字母大寫
- 駱駝文
類的命名主要有以上三個規(guī)則, 舉例如下,如一個查看圖片預(yù)覽的視圖控制器, 則命名為 ImagePreviewController, 首字母i大寫, ImagePreview交代目的, Controller告知這是一個控制器.(如果你不知道神馬是駱駝文, 那我就瞪著眼的告訴你駱駝文就像駝峰一樣,如AppleTree,一高一低快速區(qū)分單詞)
變量\常量
常量通俗用法是首字母大寫, 駱駝文寫法,如 int MaxSectionNumber;
變量首字母小寫, 駱駝文寫法, 如usernameField, nameLabel, 這種命名有助于理解用途,usename表示用戶名,field表示可以輸入?yún)^(qū)域,nameLabel表示名稱,label表示這是一個UILabel方法
方法用的比較講究一點(diǎn),具體例子如下,首先名稱名要指明方法的用途,其次,格式"-空格(返回值)方法名:(類型)參數(shù)名空格{換行}"
<pre>- (void)doSth:(NSString *)paramName {// -之后是一個空格,尾部{之前有個空格 // do sth }
</pre>-
注釋,
Objective-C支持兩種注釋
<pre>// 注釋一行代碼,注意注釋正文和斜桿間留一個空格(為了更優(yōu)美的閱讀體驗) /* 多行注釋, 包括在/* 和*/之間都是注釋內(nèi)容 */
</pre>注釋常量\變量
我一般建議對變量(常量)的注釋添加在其后面, 這樣有助于相似屬性擺在一起, 相比于"注釋一行,變量一行"的做法閱讀起來更順, 末尾有強(qiáng)迫癥的可以對齊
<pre>// 廣告類型 extern NSString *const RE_AD_TYPE_PRODUCT; //產(chǎn)品 extern NSString *const RE_AD_TYPE_EXHIBITOR; //展商 extern NSString *const RE_AD_TYPE_SESSION; //會議
</pre>這種方式是不是比下面的看起來更好看一些呢?
<pre>//產(chǎn)品 extern NSString *const RE_AD_TYPE_PRODUCT; //展商 extern NSString *const RE_AD_TYPE_EXHIBITOR; //會議 extern NSString *const RE_AD_TYPE_SESSION;
</pre>-
注釋方法
寫法見下圖, 內(nèi)容與*間留一個空格, 不同的內(nèi)容間留空行, 頂部寫方法的用途,可以一行或多行,看需要,這里可以講明下方法的思路,一些邏輯的說明,@param則解釋參數(shù)的類型,用途,如果有多個候選,則講明每個候選的意義
這里舉個失敗的例子,如代碼更新了,但是注釋未更新,或者注釋不明確
-
注釋過程
我很喜歡下面的寫法, 在動筆寫代碼前先將明確邏輯, 然后才是按照步驟完成代碼
-
代碼組織
- 通過
#pragma mark -
分隔代碼塊
這個用法有兩種,一種是帶橫線的(mark后面帶橫線), 一種是不帶橫線的(mark后面不帶橫線), 如下圖所示, 帶橫線可以將模塊區(qū)分, 不帶橫線可以對模塊內(nèi)區(qū)分,這個建議多用, 有助于代碼整潔
- BadSmell(KentBeck提出的概念), 當(dāng)你看到一段代碼在不同的地方多次出現(xiàn)的時候,你就應(yīng)該嗅出壞味, 然后將其抽出來在多個地方調(diào)用,而不是導(dǎo)出copy paste.
-
靈活使用getter
這是最近學(xué)到的一招, 為了讓代碼更加優(yōu)美, 將初始放入getter中, 這樣在真正使用的時候?qū)W⑴渲镁秃昧?/p>
- UIViewController模板
感謝 @mastertsx @十一歲的加重,
我總結(jié)了一個UIViewController的模板,有興趣的童鞋可以將它加為一個snippets, 以后新的controller就不用每次都重復(fù)機(jī)械運(yùn)動了(有建議或者意見請留言),地址是UIViewControllerTemplate
- 通過
-
怎樣讓邏輯通順
- 寫代碼前整理思路, 確定實現(xiàn)方案再動手
- 多寫工具類, 將功能抽調(diào)成工具類, 真正使用者只是使用工具, 而工具可復(fù)用
- 多看, 多思, 多實踐