鏈接:https://www.zhihu.com/question/45517397/answer/99293671
來源:知乎
著作權歸作者所有。商業轉載請聯繫作者獲得授權,非商業轉載請註明出處。
MVP 架構
MVC的C是即持有具體Model,又持有具體View,所以C很臃腫,分層架構就算抽出了DataManager,實質上仍然是一個MVC架構,而MVP和MVVM則是C持有具體View這個問題做了點文章,其中MVP就是將大量的View <-> Model 交互剝離出來交由Presenter,Presenter持有抽象的View。
在去年寫這個回答的時候,我曾經寫過這麼一段:
看上去很美好,但是網上很多博客的那種Demo寫法我在嘗試應用中發現並不實用,就是抽象出很多View接口,然後建立Presenter類來作爲Presenter,這樣做寫些簡單的列表獲取,登錄之類看起來很漂亮,好像做到了代碼分離,但是業務場景一複雜就有點蛋疼
那個時候我還僅僅只是嘗試,不實用是一個很感性的認識,也沒有多說,那時候是在做一個商城應用,使用MVP編寫諸如購物車之類複雜場景的時候遇到了很大的困難,以至於讓我懷疑我是不是在用MVP給自己找麻煩,寫登錄這些還好,寫到購物車的時候我就開始懷疑人生了。
一個ICartView,我要寫多少接口?購物車查刪改、優惠券滿減查、湊單、價格計算、運費……二十個接口少不了吧?那麼這個抽象的View除了給CartActivity用,還有其它什麼卵用嗎?
假如我寫成ICartView,IBonusView,IXXXView……可是有的界面並不需要刪改購物車列表啊,難道我還要再細分?然後讓Activity實現一堆接口?搞成這個樣子,假如哪天需求變了怎麼辦……
Presenter聽起來很吊,主導者啊,但是沒有Activity和Fragment的資源啊,我要怎麼才能讓它主導?需要獲取系統的一些信息(需要Context)的時候怎麼辦?不持有Context難道再開接口嗎?
寫這麼多接口,接口實現,Presenter,多寫了幾百行代碼n個類,就爲了把1~200行代碼從Activity移出去?
還是放棄吧……
後來Google出了TODO-MVP,但是發現跟上面那種Demo寫法一樣很麻煩,我也沒有實際運用。後來反編譯了某個大型App,發現其正好是MVP架構,於是仔細看了一下代碼,就如同我最開始的想法,一個IXXXView有多少功能就寫多少接口。再看看Presenter的實現,我忽然就明白我爲什麼會感覺不實用了:
任何想要構建一個其他什麼東西取代Activity/Fragment地位的嘗試都是自找麻煩
MVP正是一個典型
既然MVP把Activity/Fragment抽象爲View,那麼就意味着當它作爲一個抽象View去使用的時候,生命週期,Context這些極其重要的資源Presenter是看不到的,但是這些東西是不可能不使用的。爲了能讓Presenter使用到這些,Presenter就必須持有Context,綁定Activity、Fragment的生命週期,就算如此,在一些需要確定使用Activity、Fragment的場合,仍需要使用強制轉型。
正因爲Presenter這個“主導”,導致Presenter和Activity/Fragment高度綁定,Presenter和IXXXView,沒有什麼複用性。