成人免费xxxxx在线视频软件_久久精品久久久_亚洲国产精品久久久_天天色天天色_亚洲人成一区_欧美一级欧美三级在线观看

為什么Swift中應(yīng)該避免使用guard語句

移動開發(fā)
Guard語句很便于用來減少結(jié)構(gòu)體和函數(shù)的嵌套,但是問題不是guard本身,而是它的使用。Guard語句會促使你寫出能做好幾件事、有多層抽象層次的大函數(shù)。只要保證所寫的函數(shù)小而明確,你根本無需guard語句。

自從guard語句在Swift中出現(xiàn)以來,就引起了大量的討論。講真,guard確實簡化了代碼,且提高了代碼的可讀性,但它就是靈丹妙藥了嗎?

小函數(shù)

關(guān)于函數(shù)的大小,人們也討論了很多。很明顯,函數(shù)體應(yīng)該是短小的,而且是越短越好。沒有人想去讀、理解或者重構(gòu)大函數(shù)。但是,函數(shù)應(yīng)該多大才是正確的呢?

函數(shù)的首要準(zhǔn)則是--短。次要準(zhǔn)則是--更短。 ---羅伯特`C`馬丁

更具體點說,馬丁認為函數(shù)的長度應(yīng)該小于六行,絕對不能大于十行。

規(guī)則雖簡,療效顯著,你可以看到代碼立刻就變得易懂多了。以前,你需要記住一個有著30行代碼,若干縮進層次,若干中間變量的函數(shù)。而現(xiàn)在只需要記住十個名字一目了然的函數(shù)。

單一職責(zé)

單一職責(zé)這件事也被說了很久。這條規(guī)則不僅適用于對象,也同樣適用于函數(shù)。很顯然,每一個函數(shù)應(yīng)該只做一件事情,但是人們一次兩次地違反此規(guī)則,似乎大部分是因為函數(shù)的大小。如果將一個30行的函數(shù)重構(gòu)為十個3行的函數(shù),那么在函數(shù)層次自然而然地遵循單一職責(zé)規(guī)則了。

單層抽象

人們對函數(shù)的單層抽象討論得并不多.它是一個有助于寫出單一職責(zé)函數(shù)的工具。

什么是單層抽象? 簡單地說,就是高抽象層次的代碼,例如控制進程的代碼中不應(yīng)該混雜著小的細節(jié),例如變量自增或者布爾值檢驗。舉個栗子。

下面例子出自The Swift Programming Language book。

  1. struct Item { 
  2.     var price: Int 
  3.     var count: Int 
  4.   
  5. enum VendingMachineError: ErrorType { 
  6.     case InvalidSelection 
  7.     case InsufficientFunds(coinsNeeded: Int) 
  8.     case OutOfStock 
  9.   
  10. class VendingMachine { 
  11.     var inventory = [ 
  12.         "Candy Bar": Item(price: 12, count: 7), 
  13.         "Chips": Item(price: 10, count: 4), 
  14.         "Pretzels": Item(price: 7, count: 11
  15.     ] 
  16.   
  17.     var coinsDeposited = 0 
  18.   
  19.     func dispense(snack: String) { 
  20.         print("Dispensing \(snack)"
  21.     } 
  22.   
  23.     func vend(itemNamed name: String) throws { 
  24.         guard var item = inventory[name] else { 
  25.             throw VendingMachineError.InvalidSelection 
  26.         } 
  27.   
  28.         guard item.count > 0 else { 
  29.             throw VendingMachineError.OutOfStock 
  30.         } 
  31.   
  32.         guard item.price <= coinsDeposited else { 
  33.             throw VendingMachineError.InsufficientFunds(coinsNeeded: item.price - coinsDeposited) 
  34.         } 
  35.   
  36.         coinsDeposited -= item.price 
  37.         --item.count 
  38.         inventory[name] = item 
  39.         dispense(name) 
  40.     } 

當(dāng)然,vend(itemNamed:)只是使用gaurd語句的一個例子,不過你經(jīng)常能在生產(chǎn)代碼中看到相似的函數(shù)。這個函數(shù)就出現(xiàn)了三個上面說到的問題:

  1. 它相當(dāng)?shù)拈L,有十六行,很多部分由空行隔開。
  2. 它做了好幾件事:通過名稱拿到一件商品,驗證參數(shù)合法性,然后是出售商品的邏輯。
  3. 它有好幾個抽象層次。最高層的出售過程被隱藏在了更細層次的細節(jié)當(dāng)中了,例如布爾值驗證,特殊常量的使用,數(shù)學(xué)運算等等。

這個函數(shù)重構(gòu)后是什么樣呢?

  1. func vend(itemNamed name: String) throws { 
  2.     let item = try validatedItemNamed(name) 
  3.     reduceDepositedCoinsBy(item.price) 
  4.     removeFromInventory(item, name: name) 
  5.     dispense(name) 
  6.   
  7. private func validatedItemNamed(name: String) throws -> Item { 
  8.     let item = try itemNamed(name) 
  9.     try validate(item) 
  10.     return item 
  11.   
  12. private func reduceDepositedCoinsBy(price: Int) { 
  13.     coinsDeposited -= price 
  14.   
  15. private func removeFromInventory(var item: Item, name: String) { 
  16.     --item.count 
  17.     inventory[name] = item 
  18.   
  19. private func itemNamed(name: String) throws -> Item { 
  20.     if let item = inventory[name] { 
  21.         return item 
  22.     } else { 
  23.         throw VendingMachineError.InvalidSelection 
  24.     } 
  25.   
  26. private func validate(item: Item) throws { 
  27.     try validateCount(item.count) 
  28.     try validatePrice(item.price) 
  29.   
  30. private func validateCount(count: Int) throws { 
  31.     if count == 0 { 
  32.         throw VendingMachineError.OutOfStock 
  33.     } 
  34.   
  35. private func validatePrice(price: Int) throws { 
  36.     if coinsDeposited < price { 
  37.         throw VendingMachineError.InsufficientFunds(coinsNeeded: price - coinsDeposited) 
  38.     } 

雖然總行數(shù)變多了,但你應(yīng)該記住,代碼行數(shù)并不是它的最終目的。

重構(gòu)后的代碼相對于舊版的多了幾個優(yōu)點:

  1. 核心的出售函數(shù)變小了,而且只包含了出售一個商品的步驟的高層邏輯.如果讀者對細節(jié)不感興趣,通過快速地看這個高層函數(shù),她就明白了售賣過程。
  2. 這些函數(shù)更好地遵守了單一職責(zé)原則.其中有一些還可以進一步分解地更小,不過即使是當(dāng)前的形式,它們都更易讀易懂.它們將老的一大串的代碼分解成了更小的,一目了然的代碼塊。
  3. 每個函數(shù)只負責(zé)單一層次邏輯的抽象。讀者可以根據(jù)需要在不同層次間移動。那出售的過程是什么樣的呢?根據(jù)名稱確定商品是否有效,然后減少顧客的余額,再將商品從存貨清單中移除,最后顯示此商品已賣出?怎么知道商品是否有效呢?通過檢查數(shù)量和價格,那怎么知道確切的數(shù)量呢?通過和0做比較。如果讀者對細節(jié)毫無興趣,他完全可以忽略這部分內(nèi)容。

結(jié)論

Guard語句很便于用來減少結(jié)構(gòu)體和函數(shù)的嵌套,但是問題不是guard本身,而是它的使用。Guard語句會促使你寫出能做好幾件事、有多層抽象層次的大函數(shù)。只要保證所寫的函數(shù)小而明確,你根本無需guard語句。

相關(guān)閱讀

責(zé)任編輯:倪明 來源: cocoachina
相關(guān)推薦

2022-12-26 00:25:06

2018-06-08 15:27:59

云計算企業(yè)存儲

2022-05-16 09:27:37

UbuntuUbuntu LTS

2022-09-09 08:48:13

ITCIO流程

2023-02-10 10:14:59

普通索引唯一索引

2024-03-01 19:47:27

SQL數(shù)據(jù)庫

2020-06-05 14:09:42

Kubernetes容器應(yīng)用程序

2022-01-23 13:51:30

Arch LinuxLinux

2013-07-29 14:50:43

API

2015-10-20 15:59:57

注釋代碼程序

2015-10-26 09:38:52

避免注釋代碼

2018-07-30 08:20:39

編程語言Python集合

2019-01-10 13:17:15

微服務(wù)容器微服務(wù)架構(gòu)

2024-03-25 10:00:00

C++編程else

2018-07-09 14:05:16

編程語言PythonPipenv

2021-05-08 14:00:58

FedoraLinux

2020-06-21 21:25:14

物聯(lián)網(wǎng)WiFiIOT

2022-05-06 08:00:00

APIBallerina編程語言

2020-07-10 13:59:52

Kaggle代碼數(shù)據(jù)

2012-09-20 15:45:09

點贊
收藏

51CTO技術(shù)棧公眾號

主站蜘蛛池模板: 黄色大片在线免费观看 | 国产高清精品一区二区三区 | 免费av观看 | 99久久免费精品 | 久久久www成人免费无遮挡大片 | av毛片免费 | 精品福利在线 | 日韩和的一区二在线 | 99久久婷婷国产综合精品电影 | 黄色在线免费观看视频网站 | 精品视频一区二区三区在线观看 | 在线观看黄免费 | 2019精品手机国产品在线 | 国产日韩一区二区三免费 | 亚洲精品乱码8久久久久久日本 | 一区二区免费 | 久久久久久免费毛片精品 | 久久精品久久精品 | 国产精品黄色 | 国产精品综合网 | 九九久久久 | 亚洲一区二区视频在线播放 | 国产午夜精品一区二区三区四区 | 中文字幕在线三区 | 久久国产婷婷国产香蕉 | 亚洲国产aⅴ精品 | 成人黄页在线观看 | 日韩欧美大片在线观看 | 欧美 日本 国产 | 一区二区三区四区不卡视频 | 国产在线观看一区二区 | 欧美大片久久久 | 99久久精品国产一区二区三区 | 超碰综合 | 精品一区二区三区免费毛片 | 成人影院午夜 | 免费一区 | 久久精品中文字幕 | 欧美一区二区三区久久精品 | 国产精品视频在线播放 | 久久久久国产精品一区二区 |