有人提出了這樣的問題:
代碼1:
if ([responseDict[@"result"] boolValue] == false) {
[CQHud showToastWithMessage:responseDict[@"msg"]];
return;
}
/// code
代碼2:
if ([responseDict[@"result"] boolValue] == false) {
[CQHud showToastWithMessage:responseDict[@"msg"]];
} else {
/// code
}
你們更傾向于哪種寫法?
我的做法是如果if的代碼塊中的代碼比較少就用if return,想問下你們是怎么選擇的爪喘。
我認(rèn)同 J_Knight 的說法:“如果這兩組代碼是互斥關(guān)系颊亮,建議使用 if & else; 如果是要首先排除某些特殊的錯(cuò)誤情況轿秧,建議使用return”。
if-else 用來表示邏輯上的分支處理,但是在程序中有一種情況是其實(shí)我們更關(guān)心的主流程。
比如來看下面的一個(gè)簡單例子
if object is Pseron {
if ((Person *)object).age > 18 {
// is adult
}else {
error("not allowed")
}
}else {
error("not allowed")
}
其實(shí)程序只關(guān)注兩個(gè)部分:
- 判斷是否合法
- 合法后進(jìn)行對(duì)應(yīng)操作
在這種場(chǎng)景下膘壶,上面的這種寫法就顯得不夠清晰,尤其是當(dāng)判斷超過3層之后洲愤。提前return就會(huì)好的多:
if object isNot Pseron {
error("not allowed")
return
}
if object.age < 18 {
error("not allowed")
return
}
if ((Person *)object).age > 18 {
// is adult
}
這也是為什么swift要單獨(dú)推出guard關(guān)鍵字的原因颓芭。
如果從更高的抽象來看,本質(zhì)上是因?yàn)榍懊娴哪切﹔eturn是一個(gè)filter柬赐,換做FRP的寫法是這樣的:
let response: Observal<Object>
response.filter { object in
return object is Person
}.filter { object in
return object.age > 18
}.subscribNext {
// is adult
}
如果這么寫就可以明顯的看出亡问,如果是分支的邏輯就會(huì)寫在操作數(shù)據(jù)這層。前面用于提前return的部分在這個(gè)場(chǎng)景里不是一個(gè)邏輯分支肛宋。
相比是不是該用return州藕,這個(gè)代碼有個(gè)更嚴(yán)重的問題
很容易看出這是處理api返回?cái)?shù)據(jù)的代碼。這樣寫犯了一個(gè)非常嚴(yán)重且簡單的錯(cuò)誤:代碼沒有復(fù)用悼吱。
用更高一點(diǎn)目光看所暴露的問題是抽象層次低慎框。
如果這樣直接處理服務(wù)端的數(shù)據(jù)良狈,等于每一個(gè)請(qǐng)求的地方都要寫這種很傻的代碼后添。有50個(gè)api,就要寫50次[responseDict[@"result"] boolValue]
薪丁,如果有一天后端架構(gòu)調(diào)整遇西,把標(biāo)志為請(qǐng)求是否成功的字段從result字符串改為狀態(tài)碼表示呢?比如200表示成功严嗜,其他都是失敗粱檀。你的代碼要怎么維護(hù)?
每個(gè)請(qǐng)求的代碼都要取一次“msg”漫玄,彈出來煩不煩茄蚯?所有的api請(qǐng)求做一層處理,如果是錯(cuò)誤的統(tǒng)一處理一下不就好了睦优?如果所有錯(cuò)誤的請(qǐng)求要記日志渗常,這種寫法不是又要改很多地方?
抽象層次低是你只看到了原始數(shù)據(jù)汗盘,沒有看到這些數(shù)據(jù)復(fù)合后的抽象皱碘。可以理解為服務(wù)端返回的是一個(gè)Response對(duì)象隐孽,里面有返回的數(shù)據(jù)和錯(cuò)誤信息癌椿。寫起來大概是這樣:
struct Response<T: JSONMappedObject>: {
var data: T?
var rawData: [String: Any]
var msg: String?
init(json: [String: Any]) {
}
init(json: [Any]){
}
}
如果以后返回的數(shù)據(jù)要做整體變更健蕊,只會(huì)是Response這個(gè)結(jié)構(gòu)發(fā)生改變,外層的業(yè)務(wù)處理不會(huì)受影響踢俄,不用關(guān)心我要的data是怎么取出來的缩功。
代碼請(qǐng)至少要做到三件事
正確的命名,不要有重復(fù)的代碼褪贵,每個(gè)函數(shù)里的邏輯步驟不要超過7步掂之。
最開始寫代碼,先嚴(yán)格達(dá)到上面的3個(gè)目標(biāo)再想其他的吧脆丁。
不要掃二維碼
歡迎關(guān)注我的微博:@沒故事的卓同學(xué)
里面沒有任何有益的內(nèi)容世舰。