android flux 与mvp,使用 MVP 时在设计上的考量
在“FluxJava: 給 Java 使用的 Flux 庫(kù)”這篇文章中提到,設(shè)計(jì)中使用 MVP 最大的問(wèn)題,是會(huì)讓不同的畫面形成一組、一組的 Class,但各組之間是獨(dú)立的。MVP 最基本的設(shè)計(jì)概念中,只描述了同一組內(nèi) Class 如何互動(dòng),并沒(méi)有提到組內(nèi)的 Class 如何跨組與其他的 Class 互動(dòng)。當(dāng)設(shè)計(jì)上出現(xiàn)要跨組的情況時(shí),就得要仰賴設(shè)計(jì)者的功力與經(jīng)驗(yàn)了。
就 MVP 的精神,View 要負(fù)責(zé)的工作,只是把 Presenter 送來(lái)的 Model 內(nèi)容呈現(xiàn)在畫面上。并且,與使用者互動(dòng),接收使用者的意圖、收集使用者輸入的數(shù)據(jù),再交由 Presenter 處理。至于其他與 Business Logic 有關(guān)的事,不會(huì)由 View 來(lái)經(jīng)手。
畫面的切換由誰(shuí)負(fù)責(zé)
在只有單一畫面的情況之下,看起來(lái)很合理、分工明確,在設(shè)計(jì)上應(yīng)該是個(gè)無(wú)可挑剔的方案。只是當(dāng)畫面一多起來(lái),隨之出現(xiàn)了一個(gè)問(wèn)題:畫面的切換由誰(shuí)負(fù)責(zé)?
有問(wèn)題嗎?View 是負(fù)責(zé)使用者互動(dòng)的,當(dāng)然畫面的轉(zhuǎn)換由 View 來(lái)做啰!
也對(duì),以 Android 平臺(tái)為例,發(fā)送 Intent 大多是在 Activity 或是 Fragment 上處理的,再自然不過(guò)了。等新的 View 被載入后,再去啟動(dòng)與其配對(duì)的 Presenter、讓 Presenter 把數(shù)據(jù)送過(guò)來(lái)。流程上都還在設(shè)計(jì)的預(yù)想之內(nèi),跨組的工作的確就由 View 來(lái)完成即可。
在畫面與畫面的順序固定的情況下,看起來(lái)是沒(méi)什么問(wèn)題。如果畫面的切換要依據(jù)數(shù)據(jù)的狀態(tài)來(lái)決定呢?
剛才有提到,為了保持每個(gè) Class 任務(wù)的單純性,View 應(yīng)該與 Business Logic 無(wú)關(guān)。要讓 View 根據(jù)數(shù)據(jù)狀態(tài)來(lái)決定,某種程度上就是 Business Logic,這樣是不是違反了一開始提到的精神?
而且判斷時(shí)所依據(jù)的數(shù)據(jù),很可能跟 View 要顯示的內(nèi)容無(wú)關(guān),又或者是一個(gè)復(fù)雜的邏輯,又更加深了是否該放在 View 上的疑慮。
Presenter 是否要跨平臺(tái)
不放在 View 又要放在哪?Presenter 上嗎?
這應(yīng)該是在簡(jiǎn)單的 MVP 結(jié)構(gòu)之下,大多數(shù)人的選擇。當(dāng)整個(gè)結(jié)構(gòu)中,就只有 Model、View、Presenter,自然是只能由 Presenter 來(lái)存取數(shù)據(jù)庫(kù)、負(fù)責(zé)數(shù)據(jù)處理邏輯。此時(shí)再多加一項(xiàng),依據(jù)數(shù)據(jù)決定畫面切換方式,好像也沒(méi)有什么不恰當(dāng)。
先回到 Android 平臺(tái)上,來(lái)看看這樣的安排會(huì)出現(xiàn)什么情況。
Presenter 要能夠控制 Activity 的轉(zhuǎn)換,必須要取得 Context,這也意味著 Presenter 與 Android 平臺(tái)綁在一起。所以當(dāng)這樣的設(shè)計(jì)內(nèi)容,要移到不同的平臺(tái)上,Presenter 就有可能要面臨大幅度在設(shè)計(jì)上的修改。換句話說(shuō)就是,把工作放在 Presenter 上,會(huì)將設(shè)計(jì)限制在特定的平臺(tái)上。
把 Context 排除在 Presenter 之外,就可以避免這個(gè)問(wèn)題了嗎?
就算是 Presenter 不直接控制 Activity 的轉(zhuǎn)換,只決定要切換哪一個(gè) Activity,Presenter 勢(shì)必要有 Activity 的資訊,不管是 Type 或是 Class 名稱。換了一個(gè)平臺(tái),顯示畫面的 Class 還會(huì)是相同的名稱嗎?可以確定的是 Type 一定不一樣。
MVP 套用在 Android 上的問(wèn)題
那就不要跨平臺(tái),大不了新的平臺(tái)把設(shè)計(jì)再重做一次!
其實(shí)對(duì) Android 平臺(tái)來(lái)說(shuō),問(wèn)題還不止如此。以 Master-Detail 的畫面配置當(dāng)例子,不同屏幕尺寸的情況下,會(huì)有一個(gè) Activity 和二個(gè) Activity 的差別。
原本在大屏幕中,一個(gè) View、一個(gè) Presenter 就做完的事,到了小屏幕卻變成二個(gè) View,那 Presenter 也要跟著拆成二個(gè)?
假設(shè)答案是肯定的,也就是說(shuō)同一個(gè) App 里,同樣用途的畫面就做了三組 View/Presenter。不對(duì),在 Android 的 Master-Detail 的模板中,Master 的 Activity 是共用的,那豈不變成同一個(gè) View 有二個(gè) Presenter 配對(duì)?
這樣的設(shè)計(jì)好像有點(diǎn)累贅,但真的要在這樣的設(shè)計(jì)下,把流程串起來(lái)也不是不行。不過(guò),要由 Master-Detail 跳到其他畫面的工作,應(yīng)該三個(gè) Presenter 都相同,是不是要抽離出來(lái),不要在 Presenter 里做?
結(jié)果,畫面切換要由誰(shuí)負(fù)責(zé)的問(wèn)題又繞回到原點(diǎn)。
當(dāng)有使用 Service 或 BroadcastReceiver 的需求時(shí),又會(huì)引發(fā)不同的問(wèn)題。
沒(méi)有套用 MVP 之前,都是很直覺(jué)地在 Activity 中進(jìn)行 Service 的使用。Service 大部份是用來(lái)進(jìn)行后端數(shù)據(jù)處理的作業(yè),這樣的 Service 該由 View 來(lái)啟動(dòng)嗎?不是應(yīng)該透過(guò) Presenter?
現(xiàn)在前端不適合啟動(dòng) Service,那該由誰(shuí)接手?Presenter 嗎?
是比 View 合適的選擇,但這樣又會(huì)回到 Presenter 要不要獨(dú)立于平臺(tái)之外的問(wèn)題上。
再者,Service 完成作業(yè)之后,如果要以 BroadcastReceiver 的流程來(lái)通知外部。BroadcastReceiver 可以放在 Activity 上嗎?MVP 傳送數(shù)據(jù)不是都要透過(guò) Presenter?Service 在用來(lái)處理數(shù)據(jù)時(shí),算是后端,不用經(jīng)過(guò) Presenter 嗎?
MVP 設(shè)計(jì)的下一步
在“MVC 與 MVP 的抉擇”一文中提到,把 MVP 中的 View 視為 Sub System,其實(shí)并不是突發(fā)奇想。而是在導(dǎo)入 MVP 時(shí),用來(lái)應(yīng)對(duì)在設(shè)計(jì)上所碰到的諸多問(wèn)題的一個(gè)環(huán)節(jié)。
如果要深入的說(shuō)明整個(gè)構(gòu)思的內(nèi)容,由于篇幅可能會(huì)很大,未來(lái)在時(shí)間允許之下,會(huì)有更多有關(guān)這方面的文章來(lái)做討論。
總結(jié)
以上是生活随笔為你收集整理的android flux 与mvp,使用 MVP 时在设计上的考量的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。
- 上一篇: android studio替换jdk,
- 下一篇: s5原生android 5.0,三星Ga