国产精品电影_久久视频免费_欧美日韩国产激情_成年人视频免费在线播放_日本久久亚洲电影_久久都是精品_66av99_九色精品美女在线_蜜臀a∨国产成人精品_冲田杏梨av在线_欧美精品在线一区二区三区_麻豆mv在线看

面向協議編程并非銀彈

移動開發 移動應用
銀彈在軟件工程中的含義是指妄圖創造某種便捷的開發技術,從而使某個項目的實施提高效率。又或者指擺脫該項目的本質或核心,而達到超乎想象的成功。但這么做的結果卻是徒勞的。在本文中Chris介紹了Swift中的面向協議編程的濫用情況,認為很多時候有更簡單的解決辦法,面向協議編程并非銀彈。

銀彈(Silver Bullet)一詞出自IBM大型機之父Frederick P. Brooks Jr.在1986年發表的一篇關于軟件工程的經典論文《沒有銀彈:軟件工程的本質性與附屬性工作》(No Silver Bullet — Essence and Accidents of Software Engineering)。其中的“銀彈”是指一項可使軟件工程的生產力在十年內提高十倍的技術或方法。該論文強調由于軟件的復雜性本質,而使這樣“真正的銀彈”并不存在。

銀彈在軟件工程中的含義是指妄圖創造某種便捷的開發技術,從而使某個項目的實施提高效率。又或者指擺脫該項目的本質或核心,而達到超乎想象的成功。但這么做的結果卻是徒勞的。

在本文中Chris介紹了Swift中的面向協議編程的濫用情況,認為很多時候有更簡單的解決辦法,面向協議編程并非銀彈。

以下為正文:

在Swift語言中,面向協議編程很流行。在“面向協議”那兒有很多Swift代碼,一些開源庫甚至將其聲明為功能。我覺得協議在Swift中被過度濫用了,其實問題常常可以用更簡單的方式來解決。簡而言之,就是不要生搬硬套協議的條條框框,而不知變通。 

 

 

 

在WWDC2015上蘋果推出了一個Session叫“Swift中的面向協議編程”,它成了這屆大會上最有影響力的Session之一。它表明了除某些情況外,用戶可以使用面向協議的解決方案(即協議和一些符合協議的類型)來替換類層次結構(即超類和一些子類)。面向協議的解決方案更簡單、更靈活。例如,一個類只能有一個超類,但一個類型可以符合許多協議。

讓我們來看看他們在WWDC演講中解決的這個問題:一系列繪圖命令需要渲染成圖像,并將指令記錄到控制臺。通過將繪圖命令放在協議中,描述繪圖的任何代碼可以根據協議的方法來表述。協議擴展允許你根據協議的基本功能定義新的繪圖功能,并且每個符合的類型都可以自動獲得新的功能。

在上述例子中,協議解決了多種類型之間共享代碼的問題。在Swift的標準庫中,協議主要用于Collection類型,用來解決完全相同的問題。因為dropFirst用Collection類型定義,所有的Collection類型都能自動得到它。與此同時,標準庫中定義了太多的Collection相關的協議和類型,當我們想找東西時會面臨困難。這是協議的一個缺點,然而,在標準庫的情況下還是利大于弊。

現在,讓我們通過一個例子來開始。這里有一個WebService類。它使用URLSession從網絡加載實體。(實際上并不加載東西,領會意思即可):

  1. class Webservice { 
  2.   func loadUser() -> User? { 
  3.     let json = self.load(URL(string: "/users/current")!) 
  4.     return User(json: json) 
  5.   } 
  6.   func loadEpisode() -> Episode? { 
  7.     let json = self.load(URL(string: "/episodes/latest")!) 
  8.     return Episode(json: json) 
  9.   } 
  10.   private func load(_ url: URL) -> [AnyHashable:Any] { 
  11.     URLSession.shared.dataTask(with: url) 
  12.     // etc. 
  13.     return [:] // should come from the server 
  14.   } 

 

上面的代碼很短,運行正常。直到我們要測試loadUser和loadEpisode之前,沒有什么問題。現在我們要么用stub方法來模擬load,要么通過依賴注入來傳入一個模擬的URLSession。我們還可以定義一個符合URLSession的協議,然后傳遞一個測試實例。不過在這個案例中,我們采用更簡單的解決方案,將Webservice更改的部分取出并轉換為結構體:

 

  1. struct Resource<A> { 
  2.   let url: URL 
  3.   let parse: ([AnyHashable:Any]) -> A} 
  4. class Webservice { 
  5.   let user = Resource<User>(url: URL(string: "/users/current")!, parse: User.init) 
  6.   let episode = Resource<Episode>(url: URL(string: "/episodes/latest")!, parse: Episode.init) 
  7.   private func load<A>(resource: Resource<A>) -> A { 
  8.     URLSession.shared.dataTask(with: resource.url) 
  9.     // load asynchronously, parse the JSON, etc. For the sake of the example, we directly return an empty result. 
  10.     let json: [AnyHashable:Any] = [:] // should come from the server 
  11.     return resource.parse(json) 
  12.   } 

 

現在,我們可以不必通過模擬任何東西來測試user和episode了:它們是簡單的結構值。我們仍然需要測試load,但只有這一個方法需要寫測試(而不是為每個資源)。現在讓我們來添加一些協議。

取代parse函數,我們可以為能夠從JSON初始化的類型創建一個協議。

  1. protocol FromJSON { 
  2.   init(json: [AnyHashable:Any]) 
  3. struct Resource<A: FromJSON> { 
  4.   let url: URL} 
  5. class Webservice { 
  6.   let user = Resource<User>(url: URL(string: "/users/current")!) 
  7.   let episode = Resource<Episode>(url: URL(string: "/episodes/latest")!) 
  8.   private func load<A>(resource: Resource<A>) -> A { 
  9.     URLSession.shared.dataTask(with: resource.url) 
  10.     // load asynchronously, parse the JSON, etc. For the sake of the example, we directly return an empty result. 
  11.     let json: [AnyHashable:Any] = [:] // should come from the server 
  12.     return A(json: json) 
  13.   } 

 

上面的代碼可能看起來更簡單,但靈活性也大大降低。例如,你如何定義一個具有User值的數組資源?(上述面向協議的例子中,是不可能實現的,我們必須等待Swift 4或5,直至可用。)協議使代碼得以簡化,但我認為它不為自身買單,因為它大大減少了我們可以創建一個Resource的方式。

代替將user和episode作為Resource值,我們還可以使Resource成為協議并具有UserResource和EpisodeResource結構。這似乎是一個很流行的做法,因為擁有類型比只是一個值來說,“就是感覺要對一些”:

 

  1. protocol Resource { 
  2.   associatedtype Result 
  3.   var url: URL { get } 
  4.   func parse(json: [AnyHashable:Any]) -> Result} 
  5. struct UserResource: Resource { 
  6.   let url = URL(string: "/users/current")! 
  7.   func parse(json: [AnyHashable : Any]) -> User { 
  8.     return User(json: json) 
  9.   } 
  10. struct EpisodeResource: Resource { 
  11.   let url = URL(string: "/episodes/latest")! 
  12.   func parse(json: [AnyHashable : Any]) -> Episode { 
  13.     return Episode(json: json) 
  14.   } 
  15. class Webservice { 
  16.   private func load<R: Resource>(resource: R) -> R.Result { 
  17.     URLSession.shared.dataTask(with: resource.url) 
  18.     // load asynchronously, parse the JSON, etc. For the sake of the example, we directly return an empty result. 
  19.     let json: [AnyHashable:Any] = [:] 
  20.     return resource.parse(json: json) 
  21.   } 

 

但如果我們仔細看看,我們真正得到了什么?代碼變得更冗長、復雜、不直觀。并且由于關聯類型,結果最后我們可能定義一個AnyResource。EpisodeResource結構和episodeResource值有什么區別呢?它們都是全局定義的。對于結構體,名稱以大寫字母開頭;而對于值,則使用小寫字母。除此之外,結構真的沒有任何優勢。你可以將它們加入命名空間(自動補全)。所以在這種情況下,有一個值肯定會更簡短。

我在網上看到的很多代碼例子。例如,我看到這樣的協議:

 

  1. protocol URLStringConvertible { 
  2.   var urlString: String { get } 
  3. // Somewhere laterfunc sendRequest(urlString: URLStringConvertible, method: ...) { 
  4.   let string = urlString.urlString 

 

是什么打動了你?為什么不簡單地刪除協議并直接傳遞urlString呢?這樣就簡單多了。或者,一個單一方法的協議:

  1. protocol RequestAdapter { 
  2.   func adapt(_ urlRequest: URLRequest) throws -> URLRequest} 

有些爭議的是:為什么不簡單地刪除協議,并在某處傳遞函數?這樣豈不是更簡單。(除非你的協議是一個類的協議,你想要一個弱引用)。

我可以繼續展示例子,但我希望希望你已經明確我的觀點:多數情況下都有更簡單的選擇。更抽象地說,協議只是實現多態代碼的一種方式。還有許多其他方法:子類、泛型、值、函數等。使用值(例如,一個String,而不是一個URLStringConvertible)是最簡單的方法。函數(例如adapt而不是RequestAdapter)比值復雜一點,但仍然很簡單。泛型(無任何限制)比協議簡單。為了完成代碼,協議通常比類層次結構更簡單。

一個有用的啟發是,也許是考慮您的協議是依照數據還是行為來建模。對于數據,結構可能更容易。對于復雜的行為(例如,具有多個方法的委托),協議通常更容易。(標準庫的collection協議有點特別:它們并不真正描述數據,而是描述數據操作。)

也就是說,協議可能非常有用。但不要為了面向協議編程而編程。首先要審視你的問題,并嘗試以最簡單的方式來解決它。讓問題推動解決方案,而不是相反。面向協議編程本身無所謂好與壞。就像任何其他技術(函數式編程,OO,依賴注入,子類化)一樣,它可以用來解決一個問題,我們應該嘗試選擇合適的工具。有時這是一個協議,但往往,有一個更簡單的方法。

其他

責任編輯:龐桂玉 來源: 移動開發前線
相關推薦

2022-07-30 23:41:53

面向過程面向對象面向協議編程

2021-06-04 09:01:27

Cocoa 協議編程 Swift

2021-06-03 08:55:58

面向協議編程

2013-07-30 09:42:41

實現編程接口編程對象編程

2018-07-23 15:55:28

協議自定義viewSwift

2010-06-13 17:10:15

2015-03-20 09:54:44

網絡編程面向連接無連接

2010-11-17 11:31:22

Scala基礎面向對象Scala

2012-02-10 10:32:33

JavaSpring

2012-01-17 09:34:52

JavaScript

2017-04-21 09:07:39

JavaScript對象編程

2013-08-06 13:58:27

2021-03-11 13:56:13

協議Python網絡

2022-12-26 00:02:24

重構代碼軟件

2022-04-01 10:27:04

面向對象串口協議代碼

2010-07-09 11:12:09

UDP協議

2012-12-13 11:01:42

IBMdW

2009-08-24 09:46:40

面向切面編程AOP

2012-02-27 09:30:22

JavaScript

2014-05-08 14:13:00

Java面向GC
點贊
收藏

51CTO技術棧公眾號

91亚洲永久精品| 日韩第一页在线| 国产精品视频一区二区久久| 欧美日韩综合在线| 久久精品嫩草影院| 91日本在线视频| 国产精品影视天天线| 中文字幕在线视频免费观看| 亚洲毛片在线观看.| 成人精品视频| 国产九色porny| 欧美又粗又大又爽| 中文久久电影小说| 欧洲一区二区日韩在线视频观看免费 | 这里只有精品电影| 激情av综合| 日韩精品一区二区三区色偷偷| 中文字幕免费一区| 三级资源在线| 国产区精品在线观看| www.亚洲在线| 污片视频在线免费观看| 国产在线观看一区二区三区| 99久久99久久综合| 丁香花在线电影小说观看| 91免费人成网站在线观看18| 国产欧美一区二区精品忘忧草 | 成人在线观看免费播放| 97人人做人人人难人人做| 久久婷婷久久一区二区三区| 欧美黄色视屏| 亚洲va国产va天堂va久久| 欧美国产日韩a欧美在线观看| 一本大道色婷婷在线| 狠狠色噜噜狠狠色综合久 | 欧美aaaaa性bbbbb小妇| 99久久伊人精品影院| 亚洲黄色免费电影| 成人中文字幕视频| 爱福利视频一区二区| 亚洲天堂成人在线视频| 肉色丝袜一区二区| 一区二区高清不卡| 91麻豆桃色免费看| 亚洲欧美日韩久久| 成人台湾亚洲精品一区二区| 国产精品裸体瑜伽视频| 精品亚洲一区二区三区在线播放| 欧美亚洲一区| h网站久久久| 玛丽玛丽电影原版免费观看1977 | 久久一区二区三区喷水| 午夜激情av在线| 美女久久久久久久久久久| 成人黄色网址在线观看| 日韩免费电影| 国产精品啪啪啪视频| 精品一区二区三区三区| 免费在线视频一区| 九色91在线| 亚洲第一精品区| 日韩精品欧美国产精品忘忧草 | 久久人人97超碰com| 玛雅亚洲电影| 男人天堂手机在线视频| 中文字幕日韩欧美| 99久久夜色精品国产网站| 亚洲成a人片777777久久| 成人黄色片视频| 欧美第一黄网免费网站| 欧美高清在线一区| 看全色黄大色大片免费久久久| 亚洲色图 在线视频| 97精品视频在线播放| 亚洲免费伊人电影| 欧美日韩一二三四| 久久精品蜜桃| 欧美日韩精品中文字幕一区二区| 日韩一区二区麻豆国产| 精品午夜久久福利影院| 国产成+人+综合+亚洲欧美| 乱子伦视频在线看| 国产成人精品免费视频| 色偷偷成人一区二区三区91| 国产视频亚洲| 日韩影片中文字幕| 在线观看免费成人av| 国产精品久久久久久搜索| 狠狠色噜噜狠狠狠狠97| 久久久久国产精品一区三寸| 亚洲综合av一区二区三区| 日本成人a视频| 91精品国产自产在线观看永久| 欧美性感一类影片在线播放| 另类中文字幕网| 亚洲成人偷拍| 黄色av网站在线看| 国产精品久久成人免费观看| 欧美精品久久久久久久| 欧美日韩精品在线观看| 另类综合日韩欧美亚洲| 黑人久久a级毛片免费观看| 一级毛片在线播放| 欧美日韩精品中文字幕一区二区| 亚洲午夜性刺激影院| 久久久精品黄色| 一区二区三区在线电影| 成人一级福利| 99热手机在线| 国产精品午夜av在线| www.久久久久| 色婷婷亚洲精品| 国产在线精品一区在线观看麻豆| 国产精品22p| 免费av网站在线观看| 亚洲爆乳无码专区| 国产91一区二区三区| 日韩视频在线观看免费| 欧美日韩亚洲激情| 国产黑丝在线一区二区三区| 精品日本12videosex| 超碰在线资源| 人成网站免费观看| 四虎4hu永久免费入口| 国产精品中文字幕久久久| 日韩精品在线影院| 精品久久中文字幕| 99精品久久免费看蜜臀剧情介绍| 亚洲综合小说| 日韩高清二区| 久久香蕉av| h网站在线播放| 337p亚洲精品色噜噜狠狠p| 国产精品久久视频| 中文字幕国产亚洲2019| 在线视频欧美精品| 欧美激情一区二区| 久久字幕精品一区| 国产精品欧美三级在线观看| 免费看男女www网站入口在线 | 中文字幕一二三区在线观看 | 精品久久久久久中文字幕| 成人自拍视频在线观看| 欧美1区2区| 精品一区二区男人吃奶| 黄色在线免费观看网站| 中文字幕乱在线伦视频乱在线伦视频| 特级黄色录像片| 99re在线观看| 久久久免费精品视频| 精品对白一区国产伦| 福利视频第一区| 欧美激情一区二区三区| 黄色资源网久久资源365| 综合一区在线| 日本欧美韩国国产| 亚洲黄色一区二区三区| 久草资源在线| 四虎国产精品免费观看| 亚洲一区自拍| 羞羞污视频在线观看| 宅男深夜国产| 人妻精品无码一区二区三区| 视频一区国产精品| 97碰碰视频| 97在线视频一区| www.欧美三级电影.com| 亚洲国产欧美一区二区丝袜黑人| 欧美性黄网官网| 亚洲激情自拍视频| 97精品电影院| 国产成人在线观看| 日本麻豆一区二区三区视频| 欧美亚韩一区| 97精品中文字幕| 国产一区二区三区四区二区| 色悠久久久久综合先锋影音下载| 色老太综合网| 日本三级一区| 久草在线视频资源| 在线网址91| 日本视频不卡| 秋霞a级毛片在线看| 黄色在线视频观看网站| 又黄又www| 三级ai视频| 黄色毛片av| 最新黄色片网站| 2020中文字字幕在线不卡| 美女在线视频一区二区| 久章草在线视频| 国产91美女视频| 婷婷五月综合缴情在线视频| 欧美视频在线第一页| 男人添女人下部视频免费| 国产成人亚洲综合无码| 日日摸日日碰夜夜爽无码| 欧美日韩第二页| 先锋成人影院| 超碰在线图片|