成人免费xxxxx在线视频软件_久久精品久久久_亚洲国产精品久久久_天天色天天色_亚洲人成一区_欧美一级欧美三级在线观看

Android開發(fā)中的MVP架構

移動開發(fā) Android
最近越來越多的人開始談論架構。我周圍的同事和工程師也是如此。盡管我還不是特別深入理解MVP和DDD,但是我們的新項目還是決定通過MVP來構建。這篇文章是我通過研究和學習各種文章以及專題討論所總結出來的。

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

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

  • 為什么越來越多的人開始關注架構?
  • 首先,MVP是什么?
  • 哪種架構才是***的,MVC,MVVM還是MVP?
  • MVP的利與弊
  • Show me the code!!!代碼展示

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

  • 詳細生動的代碼示例
  • 如何編寫測試代碼

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

順便提一下,我于上周在當?shù)氐囊粋€研討會上對MVP架構進行了相關演講。這篇文章與當時的演講內容相差無幾。

介紹~Activity是上帝類~

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

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

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

上帝類的維護成本很高,你很難理解正在進行的操作,并且難以測試和擴展,這就是為什么要避免創(chuàng)建上帝類的黃金法則。

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

 

 

 

Activity是上帝

這是為什么需要清晰架構的原因之一。不僅會造成Activity的臃腫,還會引起其他問題,如使Activity和Fragment的生命周期變復雜,以及數(shù)據綁定等。

什么是MVP?

MVP代表Model,View和Presenter。

  • View層負責處理用戶事件和視圖部分的展示。在Android中,它可能是Activity或者Fragment類。
  • Model層負責訪問數(shù)據。數(shù)據可以是遠端的Server API,本地數(shù)據庫或者SharedPreference等。
  • Presenter層是連接(或適配)View和Model的橋梁。

下圖是基于MVP架構的模式之一。View是UI線程。Presenter是View與Model之間的適配器。UseCase或者Domain在Model層中,負責從實體獲取或載入數(shù)據。依賴規(guī)則如下: 

 

 

 

The Dependency Injection

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

 

 

 

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

依賴規(guī)則?

Uncle Bob的“The Clean Architecture”描述了依賴的規(guī)則是什么。

同心圓將軟件劃分為不同的區(qū)域,一般的,隨著層級的深入,軟件的等級也就越高。外圓是實現(xiàn)機制,內圓是核心策略。

這是上面片文章的摘要:

Enitities:

  • 可以是一個持有方法函數(shù)的對象
  • 可以是一組數(shù)據結構或方法函數(shù)
  • 它并不重要,能在項目中被不同應用程序使用即可

Use Cases

  • 包含特定于應用程序的業(yè)務規(guī)則
  • 精心編排流入Entity或從Entity流出的數(shù)據
  • 指揮Entity直接使用項目范圍內的業(yè)務規(guī)則,從而實現(xiàn)Use Case的目標

Presenters Controllers

  • 將Use Case和Entity中的數(shù)據轉換成格式最方便的數(shù)據
  • 外部系統(tǒng),如數(shù)據庫或網頁能夠方便的使用這些數(shù)據
  • 完全包含GUI的MVC架構

External Interfaces, UI, DB

  • 所有的細節(jié)所在
  • 如數(shù)據庫細節(jié),Web框架細節(jié),等等

MVC,MVP還是MVVM?

那么,哪一個才是***的呢?哪一個比其他的更優(yōu)秀呢?我能只選擇一個嗎?

答案是,NO。

這些模式的動機都是一樣的。那就是如何避免復雜混亂的代碼,讓執(zhí)行單元測試變得容易,創(chuàng)造高質量應用程序。就這樣。

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

利與弊

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

**利

  • 可測試(TDD)
  • 可維護(代碼復用)
  • 容易Reviewe
  • 信息隱蔽

**弊

  • 冗余的,尤其是小型App開發(fā)
  • (有可能)額外的學習曲線
  • 開始編寫代碼之前需要時間成本(但是我敢打賭,設計架構是所有項目開發(fā)所必需的)

show me the code!!!

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

首先,為每一個View定義接口。

  1. /** 
  2.  * Interface classes for the Top view 
  3.  */ 
  4. public interface TopView { 
  5.   
  6.     /** 
  7.      * Initialize the view
  8.      *  
  9.      * e.g. the facade-pattern method for handling all Actionbar settings 
  10.      */ 
  11.     void initViews(); 
  12.   
  13.     /** 
  14.      * Open {<a href="http://www.jobbole.com/members/57845349">@link</a> DatePickerDialog} 
  15.      */ 
  16.     void openDatePickerDialog(); 
  17.   
  18.     /** 
  19.      * Start ListActivity 
  20.      */ 
  21.     void startListActivity(); 
  22.  

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

  • TopActivity只是負責處理事件監(jiān)聽或者展示每個視圖組件
  • 所有的業(yè)務邏輯必須委托給Presenter類
  • 在MVP中,View和Presenter是一 一對應的(在MVVM中是一對多的) 
  1. public class TopActivity extends Activity implements TopView { 
  2.   
  3.   // here we use ButterKnife to inject views 
  4.   /** 
  5.    * Calendar Title 
  6.    */ 
  7.   @Bind(R.id.calendar_title) 
  8.   TextView mCalendarTitle; 
  9.   
  10.   private TopPresenter mTopPresenter; 
  11.   
  12.   @Override 
  13.   protected void onCreate(Bundle savedInstanceState) { 
  14.       super.onCreate(savedInstanceState); 
  15.       setContentView(R.layout.activity_top); 
  16.       ButterKnife.bind(this); 
  17.   
  18.       // Save TopPresenter instance in a meber variable field 
  19.       mTopPresenter = new TopPresenter(); 
  20.       mTopPresenter.onCreate(this); 
  21.   } 
  22.   
  23.   /* 
  24.    * Overrides method from the {<a href="http://www.jobbole.com/members/57845349">@link</a> TopView} interfaces 
  25.    */ 
  26.   
  27.   @Override 
  28.   public void initViews() { 
  29.       // Actionbar settins 
  30.   
  31.       // set event listeners 
  32.   } 
  33.   
  34.   @Override 
  35.   public void openDatePickerDialog() { 
  36.       DatePickerFragment.newInstance().show(getSupportFragmentManager(), 
  37.               DatePickerFragment.TAG); 
  38.   
  39.       // do not write logic here... all logic must be passed to the Presenter 
  40.       mTopPresenter.updateCalendarDate(); 
  41.   } 
  42.   
  43.   @Override 
  44.   public void startListActivity() { 
  45.       startActivity(new Intent(this, ListActivity.class)); 
  46.   } 
  47.  

這是Presenter類,最重要的一點是Presenter僅僅是連接View與Model的適配橋梁。比如,TopUseCase#saveCalendarDate()是對TopPresenter細節(jié)隱藏的,同樣對TopView也是如此。你不需要關心數(shù)據結構,也不需要關心業(yè)務邏輯是如何工作的。因此你可以對TopUseCase執(zhí)行單元測試,因為業(yè)務邏輯與視圖層是分離的。 

  1. public class TopPresenter { 
  2.   
  3.     @Nullable 
  4.     private TopView mView; 
  5.   
  6.     private TopUseCase mUseCase; 
  7.   
  8.     public TopPresenter() { 
  9.       mUseCase = new TopUseCase(); 
  10.     } 
  11.   
  12.     public void onCreate(@NonNull TopView topView) { 
  13.         mView = topView; 
  14.   
  15.         // here you call View's implemented methods 
  16.         mView.initViews(); 
  17.     } 
  18.   
  19.     public void updateCalendarDate() { 
  20.         // do not forget to return if view instances is null 
  21.         if (mView == null) { 
  22.             return
  23.         } 
  24.   
  25.         // here logic comes 
  26.         String dateToDisplay = mUseCase.getDateToDisplay(mContext.getResources()); 
  27.         mView.updateCalendarDate(dateToDisplay); 
  28.   
  29.         // here you save dateand this logic is hidden in UseCase class 
  30.         mUseCase.saveCalendarDate(); 
  31.     } 
  32.  

當然,盡管業(yè)務邏輯被實現(xiàn)在Activity類中,你依然可以執(zhí)行單元測試,只不過這會耗費很多時間,而且有些復雜。可能需要更多的時間來運行App,相反,你本應該充分利用測試類庫的性能,如Robolectric。

總結

這里沒有***藥,而且MVP也僅僅是解決方案之一,它可以與其他方法協(xié)同使用,同樣,也可以有選擇的用于不同項目。

責任編輯:龐桂玉 來源: 安卓開發(fā)精選
相關推薦

2017-02-17 10:07:02

AndroidMVP模式實例

2017-11-29 09:34:03

MVP蘇寧移動

2018-10-29 11:41:22

架構MVCAndroid

2018-12-13 10:37:13

Android開發(fā)框架

2011-05-31 08:54:37

Android開發(fā) 架構

2011-03-29 13:03:59

IronRubyWindows Pho.NET

2018-06-08 14:06:02

MVP架構Android

2009-07-06 10:36:41

敏捷開發(fā)

2024-03-01 08:23:39

2023-02-06 15:24:50

軟件開發(fā)MVP功能

2009-04-30 15:56:50

三層架構MVCMVP

2023-04-11 07:50:27

軟件架構設計

2011-01-13 14:29:54

2023-11-08 08:21:52

MVPMVVMMVI

2013-04-03 11:07:34

Android開發(fā)良好習慣有用習慣

2009-05-30 09:29:52

AndroidGoogle移動OS

2023-11-06 13:17:53

ServiceAndroid

2014-06-18 14:41:26

AndroidHandler總結

2013-01-08 13:46:58

Android開發(fā)ViewStub布局

2013-06-25 11:06:07

Android開發(fā)顏色定義方法
點贊
收藏

51CTO技術棧公眾號

主站蜘蛛池模板: 亚洲一区精品在线 | 99精品久久久久 | 午夜影院 | 亚洲区一| 欧美一区二区三区在线播放 | 日韩欧美国产精品一区二区 | 国产一区二区三区 | 国产精品地址 | 欧美亚洲国产日韩 | 中文字幕日韩欧美一区二区三区 | 欧美黄在线观看 | 国产一区二区在线视频 | 2021天天躁夜夜看 | 伊色综合久久之综合久久 | 日本黄色片免费在线观看 | 欧美电影免费观看高清 | 午夜理伦三级理论三级在线观看 | 自拍偷拍中文字幕 | 99看片网 | 国产一级在线 | 国产亚洲高清视频 | 欧美精品久久久久久 | av资源中文在线天堂 | 欧美精品综合 | 三级黄视频在线观看 | 黄色免费三级 | 黄色一级电影免费观看 | 亚洲女人天堂成人av在线 | 一区二区三区欧美 | 久久午夜精品 | 久久综合一区 | 就操在线 | 国产精品久久久久久久一区探花 | 国产精品亚洲精品日韩已方 | 日韩免费视频一区二区 | 狠狠色综合久久丁香婷婷 | 国产一区二区欧美 | www.亚洲免费 | 成人毛片在线视频 | 红桃视频一区二区三区免费 | 一级做a爰片久久毛片 |