安卓開發中的Model-View-Presenter
在軟體開發行業中找到一個Android開發的架構標準是相當複雜的。確實,在一段時間內,一個非常基礎的MVP已經被提出來打破 God-Object (完全負責所有的事情),而且,就在不久之前,谷歌提出的MVVM,使用它的體系結構組件,正在被採用(ViewModel, LiveData, LifeCycleObserver…)。儘管這些體系結構(尤其是MVVM)實現了分離組件並使其可測試和可重用的目的,但我們仍然發現了一些問題,使我們自問這是否是我們可以使用的最佳體系結構。
在第一種情況下,view和Presenter,以及presenter 和 mode都是互相需要知道的。對於MVVM,雖然ViewModel不知道View,但是View知道ViewModel,這使得重用具有不同ViewModel的視圖變得複雜。依賴項投資原則(DIP)只在一個方向得到了解(視圖=>服務,而不是服務=>視圖)。這個問題是存在的,因為兩個方向上的依賴關係的給了我們更大的內聚性和更少的耦合,但也增加了複雜性。這取決於讀者來決定這種取捨是否值得。
對於層之間的通信,在經典的MVP案例中,我們發現它是通過回調完成的(這將最終把我們的應用程序變成回調地獄),而在MVVM LiveData中使用,雖然它允許我們避免回調,但它沒有為我們提供大量的操作符來操作數據(在編寫本文時,我們只有map和switchmap)。
這些是促使我們在編寫應用程序時嘗試找到更好解決方案的主要原因。
純MVP和無controller架構(Pure Model-View-Presenter or Controlerless Architecture)
在我們的例子中,我們選擇了一個叫做純MVP的體系結構(我們通常也將其稱為無控制器的架構),它允許我們完全分離模型層的視圖。多虧了Presenter 層,它的唯一功能是將單個視圖與單個應用程序服務(也稱為interactor,或用例)連接起來;因此,為了構建一個屏幕,我們可以使用N個演示者,每個視圖服務對一個。
為了說明我在本文中解釋的內容,參考GitHub上一個小的示例/項目(純模型-視圖-演示者):Pure MVP in GitHub.。
因此,我們可以將視圖和服務理解為發出事件和接收信息的黑盒(通過輸入和輸出「電纜」),我們的Presenter將負責將組件的輸入電纜連接到另一個組件的輸出電纜,反之亦然。
此外,使用lambdas用於視圖與服務通信,使我們能夠避免直接暴露這些組件之間的可觀數據。像這樣,我們可以使用RxJava在我們的服務,所以我們可以操作數據與我們所有這個庫提供的運營商和LiveData視圖的一部分,這將使我們能夠使一個實現,意識到我們的活動的生命周期的變化,甚至使用谷歌提供的視圖模型。
View
在Android中,我們的視圖的實現將對應於一個活動或一個片段(在示例/項目中是片段),但它可以是一個ViewModel,甚至是一個可視化組件。這裡不討論視圖是由N個片段組成的活動的情況,因為每個片段都有M個演示者,我們可以假設視圖是這些片段中的每一個,儘管它們隨後被分組到一個片段中(甚至在另一個片段中)。
Service
我們的服務將負責應用所有業務邏輯並協調不同的域服務,或者直接負責嚮應用程序提供/存儲信息的存儲庫。
Infrastructure Layer
在負責嚮應用程序提供數據或存儲必要數據的層(網關、BD、共享首選項、緩存…)。每個通信通道都將使用存儲庫模式實現,並將其注入到需要它們的服務中。
好處是什麼?
正是由於使依賴服務=>視圖反轉,而且不僅依賴視圖=>服務,我們還可以做以下事情:
在運行時視圖中添加/刪除更多偵聽器
時使用多個「偵聽器」的相同視圖。例如,在單擊按鈕時,我們必須與伺服器通信並啟動跟蹤事件。
通過調試我們的應用程序,我們可以在單個站點中看到演示者,所有事件流。
為了能夠在視圖和服務組件之前應用「演示者優先」設計,定義這兩個介面,例如方法和事件
測試
在為我們的應用程序編寫測試時,重要的是我們可以測試獨立的代碼單元,這些代碼單元在應用程序的其他部分沒有副作用,它們的依賴關係可以被模仿(這些代碼單元不依賴於應用程序的其他部分)。由於在這個體系結構中,我們的組件是接收事件和發出信息的黑盒,因此很容易驗證在接收X事件時發出了信息Y。
基礎架構層(數據)也很容易測試,因為我們所要做的就是模擬伺服器的響應,為此,我們將使用來自OkHttp的MockWebServer。
發展方向?
目前,有一些體系結構,如Redux和Redux-saga,在依賴項投資的原則下工作,在某種意義上說,它們完全是事件驅動的。觀察前端架構的演變,認為Android正在接近一個類似Redux的架構並不是不合理的。
改進
有許多事情可以改進,例如:
ViewModel: 可以在視圖和表示器之間添加一個額外的層,表示器負責保存視圖的狀態。此外,這個視圖模型可以直接將數據綁定注入到XML中,並使用LiveData將可視化組件綁定到LiveData的可觀察對象。另外,在我們必須處理適配器時,研究如何實現這種綁定也是我們目前正在研究的一個挑戰。
Authentication: Github API有一個限制,如果不驗證用戶,相同的IP不能執行超過一定數量的調用(https://api.github.com/rate_limit);因此,通過Github網站添加一個使用OAuth2進行基本身份驗證可以改進這個應用程序
Pagination: 目前還沒有實現分頁機制,因此應用程序不會顯示超過一定數量的搜索結果,因此在這種體系結構中實現分頁機制可能是一個有趣的挑戰。
請關注公眾號:程序你好
※谷歌 Datally 應用增加了更多上網控制功能
※谷歌的家庭鏈接軟體現在推薦「教師認可」的應用
TAG:程序員之路 |