2016年1月3日 星期日

Android 開發 (一百零八) MVP 概念

前陣子聽了幾個高手的影片,讓我又重新開始看MVP這個程式架構,
然後這個禮拜花了點時間將這個功能實作了一下,

先說明一下MVP

MVP 就是 model - View - Presenter

通常的架構分法會是,將api 的資料分成一個class 然後presenter負責邏輯
而view 就是負責ui 的呈現

舉個簡單的例子

當點擊加入購物車的時候,會發送一個api request ,然後這時候ui 會呈現一個progressing 的樣式,當api request 回來並且是加入成功的狀態,則將按鈕狀態改為已經加入購物車

以這個範例來說

progressing 樣子 and 按鈕的文字顯示都會在view (通常都會在activity or fragment)

而 api request 通常會是在model

presenter 則是中間溝通的層級

程式的話,

在view 那層應該會看到類似這樣的code

void onShowProgressBar()
void onHideProgressBar()
void onAPIRequestSuccess()
void onAPIRequestFailed()

然後在presenter的話會有類似這樣的code

void doAddToShoppingCart()

然後在model那層
boolean addShoppingCart();

model那層關心的是  如何將加入購物車api 的資料傳回來
presenter那層關心的是 取回api資料之後要判斷為加入成功or 失敗,並且要在何時顯示progressbar 和隱藏progressbar的這個動作

view 那層關心的是  當被呼叫隱藏progressbar的時候,要實際去做 progressbar.setvisibility(View.Gone)
或者當api 成功被呼叫的時候,按鈕狀態要改為已經加入購物車的動作

所以要做相關的測試時
我們可以

測試view 利用 espresso 來測試 ui 呈現方式, mock presenter 讓他call onAPIReuqestSuccess or onAPIRequestFailed 來看看 ui 呈現的方式是否跟預期一樣

測試 presenter 利用 unit test 來測試 邏輯,mock api and view 當api 回覆加入購物車成功時,presenter是否也call 到 onAPIRequestSuccess

測試 model 利用 unit test 來測試 api ,實際去打api 或mock api 結果,判斷回傳的資料是否跟預期一樣

MVP的架構的確讓我們可以擁有很漂亮的架構,而且testable,但是他帶來的副作用就是龐大的架構,大量的class ,以及大量的interface

目前我還無法說服自己以及他人使用這個架構,縱使他有很多優點,但是增加開發成本這件事讓我思考了許久,或許未來可以想到更好的解決方案吧.

對了,這次沒有sample code 只有google 提供的 test sample
https://github.com/googlecodelabs/android-testing

有興趣的人歡迎來討論一下,大家用了MVP是否都跟預期的一樣美好?

2 則留言:

  1. 為了 testable 要分開邏輯和 Android Framework,這似乎是必要之惡

    回覆刪除
    回覆
    1. 恩...目前似乎也只有這種方式,不過這個架構真的蠻恐怖的就是...

      刪除