iOS架構學習 - VIP總結

jopen 8年前發布 | 12K 次閱讀 IOS iOS開發 移動開發

感謝@葉孤城在近一段時間組織的斗魚直播講解代碼的活動,一些開發技巧和工具讓我受益匪淺,再次感謝。

昨天是由36氪的iOS Team Leader@羅琦aidenluo講解項目的架構, 有種茅塞頓開的感覺。

所以就在這里總結一下學習到的知識點。

項目地址是: https://github.com/aidenluo177/GitHubber

1、架構比較

一直以來自己都是遵循MVC模式,這個應該是蘋果首推的開發架構,按照這個模式開發APP實現功能問題不大,但是存在的問題也非常明顯,后期項目比較大了的話,Controller會便得越來越臃腫。不利于需求的改動和維護、后面入職的小伙伴也會經常看得一頭霧水。

后來出現了MVVM、VIPER. 具體是什么就不介紹了,可以谷歌一下。

MVVM一般都會結合RAC來使用,之前了解過RAC,函數式編程的思想在某些地方用的是很方便、比如監聽一些事件。 用RAC可以很快寫出緊湊的代碼,而且封裝的很好,思路也很清晰。但是RAC的學習成本在我看來應該是最大的,看到一些開源的項目,一般都是部分功能用RAC去實現, 這里 有個純RAC的項目,不過是個人作品。團隊開發如果要每個人都熟悉RAC,估計成本太高。

VIPER 還沒有真正在項目中使用過,看了這介紹的DEMO,分層有點多,有種過度設計的感覺。

2、視頻里的VIP架構

VIP就是ViewController、Interaction、Present,看一下下面這張圖

iOS架構學習 - VIP總結

首先數據的流向是單向的、職責都狠明確,Interaction做了一些Controller的邏輯操作、Presnet主要做一些轉換的工作,例如一些數據的處理顯示,因為很多時候數據拉取回來,并不能馬上使用,通常需要而外轉換一層,最后再把處理完成的數據丟會給Controller做顯示的工作。

之前寫代碼很多時候數據都需要雙向交互,這樣的確有不確定性,開發久了有可能就忘了約定好的數據交互方式,不知不覺按照自己的邏輯開發,但是這個單向的數據流可以避免這個問題,因為有且只有一個方法,每個模塊有輸入和輸出。

視頻中作者把這個輸入和輸出的接口定義成一個協議(也就是接口),很清楚指明了數據的流向,每個協議要做的事情,

   protocol   TrendingViewControllerToInteractorPipline   {          func   refreshData  (request: TrendingDataRequest)         }        protocol   TrendingInteractorToPresenterPipline   {          func   presentData  (response: TrendingDataResponse)     }        protocol   TrendingPresenterToViewControllerPipline :  class   {          func   displayData  (viewModel: TrendingDataViewModel)         }  

每個模塊里面用了typealias關鍵字重新命名了協議,為了區分不同的模塊的協議方法,增加了可讀性。

比如在ViewController里面:

  typealias  TrendingViewControllerInput = TrendingPresenterToViewControllerPipline       typealias  TrendingViewControllerOutput = TrendingViewControllerToInteractorPipline  

輸入流只接受present的數據,方便present做好數據的轉換之后,執行視圖的渲染顯示操作。

      extension TrendingViewController: TrendingViewControllerInput {        func displayData(viewModel: TrendingDataViewModel) {    data.removeAll()    viewModel.list.forEach { data.append( $0 ) }    refreshControl?.endRefreshing()    tableView.reloadData()    }       }  

每個Controller里面都有初始化各個模塊的工作,把interactor和presnet組織起來了

  private    func   setupVIP  ()   {     let  interactor =  TrendingInteractor ()     let  presenter =  TrendingPresenter ()    output = interactor    interactor.output = presenter    presenter.output =  self     }  

再來看看Interactor的工作,這里有一個請求的worker,做數據的刷新處理工作,至于怎么去請求可以不用知道,只管結果。然后把拉取回來的數據傳遞給presnet

  extension TrendingInteract or : TrendingInteractorInput {        func refreshData(request: TrendingDataRequest) {    worker . fetchTrendingData({ ( data )  ->   Void   in      self  . output . presentData( data )    }) { (err or )  ->   Void   in      // handle error     }    }       }  

Presnet做了數據的轉換工作、生成了viewModel丟回給Controller

      extension TrendingPresenter: TrendingPresenterInput {        func presentData(response: TrendingDataResponse) {    //Transform etc...    let viewModel = TrendingDataViewModel(list: response.list.map {    var cellModel = TrendingDataViewCellModel()    cellModel.cellText =  $0 .name    cellModel.cellLink =  $0 .link    return cellModel    })    output.displayData(viewModel)    }       }  

從上面看出這簡單的操作數據流向非常明確,模塊與模塊之間只有輸入和輸出,職責也非常明確,職責明確地好處就是調試方便、找問題可以集中到出問題的部分查找、節省時間。

至于單元測試,還不太清楚、之前寫代碼也沒怎么寫過單元測試,這塊知識還是空白狀態。

原文  http://www.liuchendi.com/2015/12/27/iOS/25_iOS架構/


 本文由用戶 jopen 自行上傳分享,僅供網友學習交流。所有權歸原作者,若您的權利被侵害,請聯系管理員。
 轉載本站原創文章,請注明出處,并保留原始鏈接、圖片水印。
 本站是一個以用戶分享為主的開源技術平臺,歡迎各類分享!