MVP架構在xamarin android中的簡單使用

好幾個月沒寫文章了,使用xamarin android也快接近兩年,還有一個月職業生涯就到兩個年了,從剛出來啥也不會了,到如今回頭看這個項目,真jb操蛋(真辛苦了實施的人了,無數次吐槽怎麼這麼醜),怪本身太年輕了,還好是給指定行業的人使用。 從新學習思考以後,再看本身在項目中的某些實現的代碼,的確不盡人意,甚至想罵本身。android

項目常常改,改來該去,代碼一直增長,一個fragment也沒什麼功能,接近1000行的代碼,用region括起來,開看起來還挺整齊的,找的時候就涼了。究其緣由,沒有一種模式,全部的邏輯全寫在controller(fragment和activity裏面),固然無論瞭解不瞭解什麼框架模式、設計模式。最主要、最基本的仍是實現功能和良好的用戶體驗,一些小的項目,不須要頻繁修改需求甚至不須要MVP、MVC等模式來設計,那樣反而有點刻意設計,代碼複雜臃腫。關於android中mvp架構的介紹文章很是豐富,這裏我只是作一個學習的記錄,溫故而知新。git

程序的思想都是通用的,搞.net對於mvc框架應該是很是熟悉,webform用的目前應該不是不少。先說說android中 MVC,mvc分爲三部分 :視圖(View用戶界面)、Controller(fragmnet、activity控制器業務邏輯)、Model(數據存取); 
這裏寫圖片描述 
Model:負責數據的處理、請求網絡數據、讀取本地數據、檢驗等 
View:UI操做,控件的實際處理,更新Model層的數據,負責用戶請求通知Controller 
Controller:Activity和Fragment,初始化各類控件,加載數據、邏輯的處理,職責比較多。github

什麼是MVP

mvp是從經典的mvc模式演變而來的,可是mvc模式中的View是能夠直接訪問model的,二者的重大的區別在於:mvp中presenter隔斷model與view的通訊,view與model的交互經過presenter來實現。web

mvp將controller改爲了peresenter提出者,也改變了通訊的方向,是一個MVC的改良版,MVP的結構以下: 
這裏寫圖片描述
Model:存取數據,網絡數據、SharedPreferences、sqlite等數據的存取 
Presenter:訂閱,負責View和Model的交互,隔斷View層和Model層的交互。調用View中的相應方法展現數據 
View:Fragment、Activity、ViewGroup 這一層,處理用戶的交互和事件,並觸發Presenter中的相應操做 
mvp的優勢是: 
1.view與model不發生任何交互,view層不能持有Model層的引用,不能直接去更新Model層,必須經過Presenter層,Presenter層中也不能直接操做View及相關的UI控件,必須經過View層的引用來操做。 
2.便於測試,維護性提升,代碼結構更加清晰,能夠明顯看到Activity和 
3.View與Model分離使工程的總體架構和代碼結構很是清晰(再也不是全部的業務和邏輯都糅合在Activity、Fragment裏了),易於理解和上手。 
mvp的缺點是: 
代碼更加複雜,代碼量增長。 在使用中我也發現了不少弊端,每一個Activity、Fragment都須要劃分一套MVP,這無形之中增長不少類和接口,每次通訊都須要繁瑣的接口傳遞信息,這些肯定也演化了許多版本的MVP,更多詳細能夠參考:傳統MVP用在項目中是真的方便仍是累贅? 
實踐是檢驗真理的惟一標準,下面經過一個簡單的例子獲取天氣預報信息看看,如何在xamarin android項目如何使用MVP架構吧sql

使用mvp架構實現查詢公網備案的例子

天氣預報的接口:https://www.sojson.com/api/gongan/域名,根據域名查詢備案信息 
返回的格式是json. 
若是你想更深刻地瞭解mvp架構,能夠參看一下google官方MVP框架源碼解析之TODO-MVP 
https://github.com/googlesamples/android-architecture/tree/todo-mvp/ 
效果圖以下: 
 
項目的結構以下: 
這裏寫圖片描述 
新建peresenter文件夾,GongAnPresenter.cs 以下:json

 1     public class GongAnPresenter
 2     {
 3         private IGongAnView view;
 4         public GongAnPresenter(IGongAnView view)
 5         {
 6             this.view = view;
 7         }
 8         public async void showResult(string sitedomain)
 9         {
10             var result = await SearchGongAn.getGonganDetail(sitedomain);
11             if (result != null && result.status == 200)
12                 view.getServiceGongAnSuccess(result.data);
13             else if (result == null)
14             {
15                 view.getServiceGonganFail("請求失敗");
16             }
17             else
18             {
19                 view.getServiceGonganFail("沒有備案:status:"+result.status);
20             }
21         }
22     }
 

  新建Views文件夾 ,IGongAnView.cs 接口 以下設計模式

    public interface IGongAnView
    {
        void getServiceGongAnSuccess(Data model);
        void getServiceGonganFail(string  error);
    }

新建Model文件夾,SearchGongAn.cs以下:api

 1     public class SearchGongAn
 2     {
 3        private  static string  url= "https://www.sojson.com/api/gongan/{0}";
 4         public static async System.Threading.Tasks.Task<GongAnModel> getGonganDetail(string city)
 5         {
 6             try
 7             {
 8                 HttpWebRequest request = (HttpWebRequest)HttpWebRequest.Create(string.Format(url, city));
 9                 request.Method = "get";
10                 HttpWebResponse response = (HttpWebResponse)request.GetResponse();
11                 Stream responseStream = response.GetResponseStream();
12                 StreamReader streamReader = new StreamReader(responseStream, Encoding.GetEncoding("utf-8"));
13                 string result = await streamReader.ReadToEndAsync();
14                 GongAnModel model = JsonConvert.DeserializeObject<GongAnModel>(result);
15                 streamReader.Close();
16                 responseStream.Close();
17                 return model;
18             }
19             catch (Exception ex)
20             {
21                 Log.Info("ex",ex.ToString());
22                 return null;
23             }
24         }
25     }

 

 

Mainactivity.cs網絡

 1  [Activity(Label = "PeresenterForXamarinAndroid", MainLauncher = true, Icon = "@drawable/icon")]
 2     public class MainActivity : Activity,IGongAnView,View.IOnClickListener
 3     {
 4         TextView txt_result;
 5         Button btn_search;
 6         EditText btn_sitedomain;
 7         GongAnPresenter presenter;
 8         ProgressDialog progressDialog;
 9         protected override void OnCreate(Bundle bundle)
10         {
11             base.OnCreate(bundle);
12             SetContentView(Resource.Layout.Main);
13             txt_result = FindViewById<TextView>(Resource.Id.txt_result);
14             btn_search = FindViewById<Button>(Resource.Id.btn_search);
15             btn_sitedomain = FindViewById<EditText>(Resource.Id.btn_sitedomain);
16             presenter = new Peresenter.GongAnPresenter(this);
17             progressDialog = new ProgressDialog(this);
18             progressDialog.SetTitle("搜索公網備案");
19             progressDialog.SetMessage("正在搜索,請稍後.....");
20             btn_search.SetOnClickListener(this);
21         }
22 
23         public void OnClick(View v)
24         {
25             if (v.Id == Resource.Id.btn_search)
26             {
27                 string sitedomain = btn_sitedomain.Text;
28                 string pattern = @"^[a-zA-Z0-9][-a-zA-Z0-9]{0,62}(\.[a-zA-Z0-9][-a-zA-Z0-9]{0,62})+$";
29                 Regex reg = new Regex(pattern);
30                 if (string.IsNullOrEmpty(sitedomain))
31                 {
32                     Toast.MakeText(this, "請輸入域名", ToastLength.Short).Show();
33                 }
34                 else if (reg.IsMatch(sitedomain))
35                 {
36                     progressDialog.Show();
37                     presenter.showResult(sitedomain);
38                 }
39                 else
40                 {
41                     Toast.MakeText(this, "域名錯誤,請從新輸入", ToastLength.Short).Show();
42                 }
43             }
44         }
45         public void getServiceGongAnSuccess(Data model)
46         {
47             progressDialog.Hide();
48             txt_result.Text = "工信部更新日期:" + model.cdate.ToShortDateString() + "\n公司地址:" + model.comaddress + "\n公司名稱:" + model.comname + "\n網備案號:" + model.id + "\n域名" + model.sitedomain + "\n簡稱:" + model.sitename;
49         }
50 
51         public void getServiceGonganFail(string error)
52         {
53             progressDialog.Hide();
54             txt_result.Text = "查詢失敗";
55             Toast.MakeText(this,error,ToastLength.Short).Show();
56         }
57     }

 

總結

紙上得來終覺淺,絕知此事要躬行。只要不斷實踐,豐富項目經驗,架構模式在初學者前期並非那麼重要。android開發無外乎就三種架構MVC、MVP、MVVM。MVP模式簡單易用很是容易上手,Presenter隔斷了View和Model的聯繫,做爲二者溝通的橋樑,在Activityhe fragment中你的代碼就不會變得臃腫,雜亂了。 
引用一句我很是喜歡的話:架構

架構只是一種思惟模式,不論是MVC、MVP仍是MVVM,都只是一種思考問題的思惟,其目的仍是要解決變成過程當中高內聚、低耦合、可維護、易測試。

相關文章
相關標籤/搜索