首先我們要熟記幾個(gè)原則
1. 單一職責(zé) (solid 原則)
- 一個(gè)類(lèi)應(yīng)該只做一類(lèi)事情
- 一個(gè)方法最多只做一件事情
郵件類(lèi)就應(yīng)該只發(fā)送郵件,但是不關(guān)心發(fā)給誰(shuí),你告訴我發(fā)給誰(shuí)我就發(fā)給誰(shuí)
如果你發(fā)現(xiàn)你在Mail.php里 使用了 User::find() , 這樣的語(yǔ)句存在的時(shí)候,就真的是在亂搞了 (我也這樣覺(jué)得)
第二個(gè)原則:不要做超前的設(shè)計(jì)
就是,你不要覺(jué)得“這代碼以后應(yīng)該會(huì)用到,先留著吧”
這樣是不正確的,用到的時(shí)候再加吧,不要做這些提前的過(guò)度設(shè)計(jì)
當(dāng)然,一個(gè)良好的可拓展的系統(tǒng)是以后方便拓展的基礎(chǔ)啦
第三:三次原則
當(dāng)然這個(gè)為啥是三次,我的理解是:
重復(fù)一兩次(當(dāng)然不是大段大段的,一般是一個(gè)小的轉(zhuǎn)換代碼這樣的幾行)對(duì)于閱讀來(lái)講比打開(kāi)另外的一個(gè)類(lèi),一個(gè)文件去找這個(gè)方法要方便得多, 也不是很冗余,所以說(shuō)在第三次重復(fù)的時(shí)候才抽出去,這只是一個(gè)折中的點(diǎn)吧
這三個(gè)原則是比較基礎(chǔ)的了
還有很多當(dāng)然是可以讓你代碼寫(xiě)得更好的原則定義,可以去翻閱大神的一些文章
另外說(shuō)一下我個(gè)人寫(xiě)代碼的一些思路,及從大神同事那里學(xué)到的一些技巧
寫(xiě)代碼的方法,可以考慮以樹(shù)狀結(jié)構(gòu)來(lái)寫(xiě)
什么是樹(shù)狀結(jié)構(gòu)呢?
比如我們現(xiàn)在寫(xiě)一個(gè)公司內(nèi)部用的圖書(shū)館
其中的一個(gè)邏輯是擁有一本書(shū)的人通過(guò)表單創(chuàng)建一條貢獻(xiàn)
那么這是一個(gè)action要完成的業(yè)務(wù)邏輯
我們第一步,對(duì)它進(jìn)行拆分:
- 驗(yàn)證輸入
- 拿輸入的ISBN從豆瓣取書(shū)的信息
- 創(chuàng)建Book實(shí)體并寫(xiě)入數(shù)據(jù)庫(kù)
- 創(chuàng)建Contribution實(shí)體并寫(xiě)入數(shù)據(jù)庫(kù)
- 響應(yīng)
這是 postContributon 這個(gè)動(dòng)作所包含的最頂層的邏輯劃分

我們的代碼第一步已經(jīng)完成了
下一步怎么辦?給每個(gè)邏輯起個(gè)名
當(dāng)然了,第1與第5就不用了,框架封裝的比較好了

于是代碼變成了這樣
這時(shí)候 getBookFromDouban createContribution 這些方法都還沒(méi)有寫(xiě)的,所以參數(shù)設(shè)計(jì)并不一定正確,后續(xù)發(fā)現(xiàn)不對(duì)再回來(lái)修改
然后你再去創(chuàng)建這些子方法,記?。簞?chuàng)建子邏輯方法的時(shí)候同樣使用這個(gè)方式去拆s分
那其實(shí)這就是我說(shuō)的樹(shù)狀結(jié)構(gòu)的寫(xiě)法:
- 拆分邏輯變成步驟的注釋?zhuān)?/li>
- 將注釋視復(fù)雜度變成方法,
- 遞歸對(duì)方法使用此技巧
下面聊一下如何拆分“類(lèi)”
做一個(gè)復(fù)雜模塊的時(shí)候,很多人一聽(tīng)到這個(gè)需求描述的時(shí)候就嚇暈了
比如,我們現(xiàn)在要做一個(gè)登錄模塊(以微博API的登錄為例)
微博API的認(rèn)證流程分為4-5類(lèi)(有些已經(jīng)廢棄)
比如:
- 賬號(hào)密碼登錄,
- 掃碼登錄,
- QQ, 支付寶等 OAuth 登錄,
- 短信登錄(真的很奇葩),
- 其它同站業(yè)務(wù)使用 access token 登錄
每個(gè)業(yè)務(wù)的實(shí)現(xiàn)都不一樣
怎么辦?很多新手已經(jīng)傻了,打開(kāi)IDE , if ($method == 1)..elseif ($method == 2).... N
就開(kāi)始寫(xiě)了 這是不對(duì)的!!!
那么這時(shí)候就是理清思路的時(shí)候了
幾個(gè)詞:Who, How, What
- 參與者:這個(gè)邏輯里的參與者, 憑證(Credential),會(huì)話(huà)狀態(tài)(Session),用戶(hù)(User)
- 怎么做:這個(gè)是動(dòng)詞,所以不應(yīng)該以動(dòng)詞來(lái)為類(lèi)命名,最終它的產(chǎn)物應(yīng)該是設(shè)計(jì)模式,比如這個(gè)模塊可以用適配器模式。
- 做什么:它通常定義了整個(gè)模塊的名稱(chēng),Login
所以最終的代碼可以寫(xiě)成:

- Manager 是主控,負(fù)責(zé)接收輸入,創(chuàng)建對(duì)應(yīng)的登錄器
- Authenticator, 完成登錄動(dòng)作,并返回登錄用戶(hù),保存會(huì)話(huà)這么一些大局觀的動(dòng)作
- Credential 完全就像模型了(或者實(shí)體),只是承載對(duì)應(yīng)授權(quán)方式所需要的信息,比如Credential\Password 里應(yīng)該有用戶(hù)名與密碼,同時(shí) getUsername(), getPassword() 提供這些方法
- 最后兩個(gè)就不用講了,User 是同一個(gè),無(wú)論 你用什么方式登錄,最后都得到的是一個(gè)用戶(hù),所以它只是最后的產(chǎn)出
- Session 這里就不講了大家都熟悉

所以文件與職責(zé)已經(jīng)拆分完成了s
過(guò)了一個(gè)月后,老大說(shuō):我要加一個(gè)微信登錄?。。?!
沒(méi)問(wèn)題,不就是加一個(gè)Credential 與 Authenticator 就完事了,互不干擾
哈哈,NB吹完了。