Android開發中的MVP架構

來源:互聯網
上載者:User

標籤:

  寫在前面,本部落格來源於公眾號文章:http://mp.weixin.qq.com/s?__biz=MzA3MDMyMjkzNg==&mid=402435540&idx=1&sn=1cd10bd9efaac7083575367a8b4af52f&scene=1&srcid=0910ARzPpBvVYPI1NDBZnixa#wechat_redirect

 

 

最近越來越多的人開始談論架構。我周圍的同事和工程師也是如此。儘管我還不是特別深入理解MVP和DDD,但是我們的新項目還是決定通過MVP來構建。

 

這篇文章是我通過研究和學習各種文章以及專題討論所總結出來的,它包括以下幾點:

 

  • 為什麼越來越多的人開始關注架構?

  • 首先,MVP是什嗎?

  • 哪種架構才是最好的,MVC,MVVM還是MVP?

  • MVP的利與弊

  • Show me the code!!!代碼展示

 

不幸的,這篇文章將不包括:

 

  • 詳細生動的程式碼範例

  • 如何編寫測試代碼

 

最後,我將告訴你如何更進一步學習這些專題。

 

順便提一下,我於上周在當地的一個研討會上對MVP架構進行了相關演講。這篇文章與當時的演講內容相差無幾。

 

(譯者註:閱讀更多請點擊原作者PPT)

 

介紹~Activity是上帝類~

 

首先,讓我們思考一下為什麼在Android開發中如此迫切地需要一個清晰的軟體架構。

 

該段摘自“代碼大全第二版”:

 

避免建立神類。避免建立無所不知,無所不能的上帝類。如果一個類需要花費時間從其他類中通過Get()和Set()檢索資料(也就是說,需要深入業務並且告訴它們如何去做),所以是否應該把這些功能函數更好的組織到其它類而不是上帝類中。(Riel 1996)

 

上帝類的維護成本很高,你很難理解進行中的操作,並且難以測試和擴充,這就是為什麼要避免建立上帝類的黃金法則。

 

然而,在Android開發中,如果你不考慮架構的話,Activity類往往會越來越大。這是因為,在Android中,允許View和其它線程共存於Activity內。其實最大的問題莫過於在Activity中同時存在商務邏輯和UI邏輯。這會增加測試和維護的成本。

 

Activity是上帝

 

這是為什麼需要清晰架構的原因之一。不僅會造成Activity的臃腫,還會引起其他問題,如使Activity和Fragment的生命週期變複雜,以及資料繫結等。

 

什麼是MVP?

 

MVP代表Model,View和Presenter。

 

  • View層負責處理使用者事件和視圖部分的展示。在Android中,它可能是Activity或者Fragment類。

  • Model層負責訪問資料。資料可以是遠端的Server API,本機資料庫或者SharedPreference等。

  • Presenter層是串連(或適配)View和Model的橋樑。

 

是基於MVP架構的模式之一。View是UI線程。Presenter是View與Model之間的適配器。UseCase或者Domain在Model層中,負責從實體擷取或載入資料。依賴規則如下:

 

The Dependency Injection

 

關鍵是,高層介面不知道底層介面的細節,或者更準確地說,高層介面不能,不應該,並且必須不瞭解底層介面的細節,是(面向)抽象的,並且是細節隱藏的。

 

The higher interfaces do not know about the details of the lower ones

 

依賴規則?

 

Uncle Bob的“The Clean Architecture”描述了依賴的規則是什麼。

 

同心圓將軟體劃分為不同的地區,一般的,隨著層級的深入,軟體的等級也就越高。外圓是實現機制,內圓是核心策略。

 

這是上面片文章的摘要:

 

Entities:

 

  • 可以是一個持有方法函數的對象

  • 可以是一組資料結構或方法函數

  • 它並不重要,能在項目中被不同應用程式使用即可

 

Use Cases

 

  • 包含特定於應用程式的商務規則

  • 精心編排流入Entity或從Entity流出的資料

  • 指揮Entity直接使用專案範圍內的商務規則,從而實現Use Case的目標

 

Presenters,,Controllers

 

  • 將Use Case和Entity中的資料轉換成格式最方便的資料

  • 外部系統,如資料庫或網頁能夠方便的使用這些資料

  • 完全包含GUI的MVC架構

 

External Interfaces, UI, DB

 

  • 所有的細節所在

  • 如資料庫細節,Web架構細節,等等

 

MVC,MVP還是MVVM?

 

那麼,哪一個才是最好的呢?哪一個比其他的更優秀呢?我能只選擇一個嗎?

 

答案是,NO。

 

這些模式的動機都是一樣的。那就是如何避免複雜混亂的代碼,讓執行單元測試變得容易,創造高品質應用程式。就這樣。

 

當然,遠不止這三種架構模式。而且任何一種模式都不可能是銀彈,他們只是架構模式之一,不是解決問題的唯一途徑。這些只是方法、手段而不是目的、目標。

 

利與弊

 

OK,讓我們回到MVP架構上。剛剛我們瞭解了什麼是MVP,討論了MVP以及其它熱門架構,並且介紹了MVC,MVP和MVVM三者間的不同。這是關於MVP架構利與弊的總結:

 

**利

 

  • 可測試(TDD)

  • 可維護(代碼複用)

  • 容易Reviewe

  • 資訊隱蔽

 

**弊

 

  • 冗餘的,尤其是小型App開發

  • (有可能)額外的學習曲線

  • 開始編寫代碼之前需要時間成本(但是我敢打賭,設計架構是所有項目開發所必需的)

 

Show me the code!!!

 

這裡僅展示了MVP模式的一小段結構。如果你想瞭解更多項目或生動的程式碼範例,請參考文章末尾的“連結和資源”。那裡有非常豐富和設計巧妙的樣本,基本都託管在Github上,以便你能clone,在裝置上運行,並瞭解工作原理。

 

首先,為每一個View定義介面。

 

/**

* Interface classes for the Top view

*/

public interface TopView {

 

/**

* Initialize the view.

*

* e.g. the facade-pattern method for handling all Actionbar settings

*/

void initViews();

 

/**

* Open {<a href="http://www.jobbole.com/members/57845349">@link</a> DatePickerDialog}

*/

void openDatePickerDialog();

 

/**

* Start ListActivity

*/

void startListActivity();

}

 

讓我們重寫TopView類,要點如下:

 

  • TopActivity只是負責處理事件監聽或者展示每個視圖組件

  • 所有的商務邏輯必須委託給Presenter類

  • 在MVP中,View和Presenter是一 一對應的(在MVVM中是一對多的)

 

public class TopActivity extends Activity implements TopView {

 

// here we use ButterKnife to inject views

/**

* Calendar Title

*/

@Bind(R.id.calendar_title)

TextView mCalendarTitle;

 

private TopPresenter mTopPresenter;

 

@Override

protected void onCreate(Bundle savedInstanceState) {

super.onCreate(savedInstanceState);

setContentView(R.layout.activity_top);

ButterKnife.bind(this);

 

// Save TopPresenter instance in a meber variable field

mTopPresenter = new TopPresenter();

mTopPresenter.onCreate(this);

}

 

/*

* Overrides method from the {<a href="http://www.jobbole.com/members/57845349">@link</a> TopView} interfaces

*/

 

@Override

public void initViews() {

// Actionbar settins

 

// set event listeners

}

 

@Override

public void openDatePickerDialog() {

DatePickerFragment.newInstance().show(getSupportFragmentManager(),

DatePickerFragment.TAG);

 

// do not write logic here... all logic must be passed to the Presenter

mTopPresenter.updateCalendarDate();

}

 

@Override

public void startListActivity() {

startActivity(new Intent(this, ListActivity.class));

}

}

 

這是Presenter類,最重要的一點是Presenter僅僅是串連View與Model的適配橋樑。比如,TopUseCase#saveCalendarDate()是對TopPresenter細節隱藏的,同樣對TopView也是如此。你不需要關心資料結構,也不需要關心商務邏輯是如何工作的。因此你可以對TopUseCase執行單元測試,因為商務邏輯與視圖層是分離的。

 

public class TopPresenter {

 

@Nullable

private TopView mView;

 

private TopUseCase mUseCase;

 

public TopPresenter() {

mUseCase = new TopUseCase();

}

 

public void onCreate(@NonNull TopView topView) {

mView = topView;

 

// here you call View‘s implemented methods

mView.initViews();

}

 

public void updateCalendarDate() {

// do not forget to return if view instances is null

if (mView == null) {

return;

}

 

// here logic comes

String dateToDisplay = mUseCase.getDateToDisplay(mContext.getResources());

mView.updateCalendarDate(dateToDisplay);

 

// here you save date, and this logic is hidden in UseCase class

mUseCase.saveCalendarDate();

}

}

 

當然,儘管商務邏輯被實現在Activity類中,你依然可以執行單元測試,只不過這會耗費很多時間,而且有些複雜。可能需要更多的時間來運行App,相反,你本應該充分利用測試類別庫的效能,如Robolectric。

 

總結

 

這裡沒有萬能藥,而且MVP也僅僅是解決方案之一,它可以與其他方法協同使用,同樣,也可以有選擇的用於不同項目。

 

連結和資源

 

The Clean Architecture(譯者註:清晰架構。譯文) – Uncle Bob

http://blog.8thlight.com/uncle-bob/2012/08/13/the-clean-architecture.html

 

這篇文章由Uncle Bob撰寫,描述了依賴規則的樣子和它們之間的組件是如何工作的。我從一開始談論的那張圖表的靈感就來源於他的文章,雖然這篇文章不是針對Android開發的,但是同往常一樣,字裡行間蘊藏著很多精闢的道理,所以,必讀。

 

Architecting Android…The clean way? (譯者註:Android中的清晰架構。譯文)- Fernando Cejas

http://fernandocejas.com/2014/09/03/architecting-android-the-clean-way/

 

我認為這是在探索如何將MVP架構到Android開發專題中最著名,也是最受歡迎的部落格。我也是從他那篇簡單易讀,書寫良好的部落格中偶然發現“MVP”這個名詞的。他的範例程式碼託管在Github上,以便那些想要將MVP架構運用到正式App上的Android開發人員clone到。

 

Android Architecture(譯者註:Android架構) – Thanos Karpouzis

https://medium.com/android-news/android-architecture-2f12e1c7d4db#.7ch5tkkx0

 

一個在Android項目中運用MVC,MVP,MVVM的簡單指導。我從他的那篇普通卻不平凡的文章中學到了很多,尤其是MVC,MVP和MVVM之間的不同。

 

Software Design patterns on Android English(譯者註:Android開發中的軟體設計模式) – Pedro Vicente Gómez Sánchez

http://www.slideshare.net/PedroVicenteGmezSnch/software-design-patterns-on-android

 

這是一個在Karumi工作的進階Android開發工程師所講的,他解釋了一些MVP架構中的設計模式(如,渲染模式,倉庫模式和命令模式)。如果你想深入理解MVC或者MVP,那這就使你要找的。

 

M?—?Model in MVC, MVP, MVVC in Android(譯者註:MVC,MVP,MVVC架構中Model層在Android中的定義) – Artem Zinnatullin

https://medium.com/@artem_zin/m-model-from-mvc-mvp-in-android-flow-and-mortar-bd1e50c45395#.82qjulegz

 

如果你不還瞭解Model層中的JSON與SQL,或者不能透徹理解Model層的映像模型,這篇文章將帶你進一步理解什麼是Model層以及為什麼Model層獨立於其他層。其中“Model layer is solution”部分很好的解釋了如何通過面向介面的方式編寫測試。

 

Android開發中的MVP架構(轉)

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.