Android的MVC框架

http://www.cnblogs.com/wanghafan/archive/2012/07/20/2600786.htmlhtml

MVC是當前比較流行的框架,隨便Google下,就能夠發現幾乎全部的應用程序開發中都採用了MVC框架,例如:.NET,Java Spring,Java Struts,PHP 。那麼MVC究竟是什麼,爲何被普遍使用? java

簡要說明下,什麼是MVC。MVC (Model-View-Controller):M是指邏輯模型,V是指視圖模型,C則是控制器。一個邏輯模型能夠對於多種視圖模型,好比一批統計數據你能夠分別用柱狀圖、餅圖來表示。一種視圖模型也能夠對於多種邏輯模型。使用MVC的目的是將M和V的實現代碼分離,從而使同一個程序可使用不一樣的表現形式,而C存在的目的則是確保M和V的同步,一旦M改變,V應該同步更新,這與《設計模式》中的觀察者模式是徹底同樣。具體詳細的解析,能夠去閱讀百度知道中介紹的什麼是MVC? android

採用MVC到底有什麼好處?從用戶的角度出發,用戶能夠根據本身的需求,選擇本身合適的瀏覽數據的方式。好比說,對於一篇在線文檔,用戶能夠選擇以HTML網頁的方式閱讀,也能夠選擇以pdf的方式閱讀。從開發者的角度,MVC把應用程序的邏輯層與界面是徹底分開的,最大的好處是:界面設計人員能夠直接參與到界面開發,程序員就能夠把精力放在邏輯層上。而不是像之前那樣,設計人員把全部的材料交給開發人員,由開發人員來實現界面。在VS 2008開發工具中設計人員就能夠直接經過Silverlight來開發界面,在Eclipes工具中開發Android採用了更加簡單的方法,設計人員在DroidDraw中設計界面,以XML方式保存,在Eclipes中直接打開就能夠看到設計人員設計的界面。 程序員

Android中界面部分也採用了當前比較流行的MVC框架,在Android中M就是應用程序中二進制的數據,V就是用戶的界面。Android的界面直接採用XML文件保存的,界面開發變的很方便。在Android中C也是很簡單的,一個Activity能夠有多個界面,只須要將視圖的ID傳遞到setContentView(),就指定了以哪一個視圖模型顯示數據。 web

在Android SDK中的數據綁定,也都是採用了與MVC框架相似的方法來顯示數據。在控制層上將數據按照視圖模型的要求(也就是Android SDK中的Adapter)封裝就能夠直接在視圖模型上顯示了,從而實現了數據綁定。好比顯示Cursor中全部數據的ListActivity,其視圖層就是一個ListView,將數據封裝爲ListAdapter,並傳遞給ListView,數據就在ListView中現實。 設計模式

目前Android中採用的MVC框架仍是比較簡單的,在將來還會不斷完善。Android SDK若是要實現相似與MFC中視圖/文檔模型(View/Document Model),恐怕還須要等待一些時日,讓咱們拭目以待吧。  app

MVC進行重構 框架

感謝:http://code.google.com/p/androidbmi/wiki/BmiRefactor寫的很是的好,通俗易懂而又不顯囉嗦,真是恰到好處啊! ide

本文僅以代碼說話,主要是方便本身回想這樣重構的好處,記錄一下本身重構過程當中的思路邏輯,更多的文字介紹請看前面那個連接! 函數

Step1抽取全部界面元件的聲明和定義,整合到單獨一個函數findViews()中;

複製代碼
 1 // 聲明
 2 private Button button_calc;
 3 private EditText field_height;
 4 private EditText field_weight;
 5 private TextView view_result;
 6 private TextView view_suggest;
 7 
 8 // 定義
 9 private void findViews() {
10     button_calc = (Button) findViewById(R.id.submit);
11     field_height = (EditText) findViewById(R.id.height);
12     field_weight = (EditText) findViewById(R.id.weight);
13     view_result = (TextView) findViewById(R.id.result);
14     view_suggest = (TextView) findViewById(R.id.suggest);
15 }
複製代碼

此部分便是MVC中的V:View視圖。

Step2抽取程序的邏輯(即界面元件的處理邏輯),整合到函數setListensers()中;

1 //Listen for button clicks
2 private void setListensers() {
3     button_calc.setOnClickListener(calcBMI);
4 }

此部分便是MVC中的C:Controller控制器。

接着,onCreate()就顯得很是簡潔、明瞭了:

複製代碼
1 public void onCreate(Bundle savedInstanceState) {
2     super.onCreate(savedInstanceState);
3     setContentView(R.layout.main);
4 
5     findViews();
6     setListensers();
7 }
複製代碼

Step3修改按鈕監聽器calcBMI中相應的部分(主要是變量已經在視圖部分定義了);

複製代碼
 1 private OnClickListener calcBMI = new OnClickListener() {
 2     @Override
 3     public void onClick(View v) {
 4         DecimalFormat nf = new DecimalFormat("0.00");
 5 
 6         double height = Double.parseDouble(field_height.getText().toString()) / 100;
 7         double weight = Double.parseDouble(field_weight.getText().toString());
 8         double BMI = weight / (height * height);
 9 
10         // Present result
11         view_result.setText("Your BMI is " + nf.format(BMI));
12 
13         // Give health advice
14         if (BMI > 25) {
15             view_suggest.setText(R.string.advice_heavy);
16         } else if (BMI < 20) {
17             view_suggest.setText(R.string.advice_light);
18         } else {
19             view_suggest.setText(R.string.advice_average);
20         }
21     }
22 };
複製代碼

Step4修剪一下「細枝末節」;

1)        calcBMI的修改:

1 private OnClickListener calcBMI = new OnClickListener() {
2     ……
3 }

改爲以下:

1 private Button.OnClickListener calcBMI = new Button.OnClickListener() {
2     ……
3 }

gasolin的解釋是:

同樣是「calcBMI」 函式,在完整程式中,改將「calcBMI」 函式從本來的「OnClickListener」宣告成 「Button.OnClickListener」。這個改變有什麼差別呢?

閱讀本來的程式碼,在匯入(import)的部分能夠看到,「OnClickListener」是來自於「android.view.View.OnClickListener」函式:

    import android.view.View.OnClickListener;

改爲 「Button.OnClickListener」後,「Button.OnClickListener」就變成來自於「android.widget.Button」中的「OnClickListener」函式,在查閱程式時,整個「Button」與「OnClickListener」之間的關係變得更清晰。

2)        字符串統一引用XML中的描述符:

//Present result

view_result.setText("Your BMI is " + nf.format(BMI));

改爲以下:

//Present result

view_result.setText(getText(R.string.bmi_result) + nf.format(BMI)); 

總之,此重構的目的無非是使程序的脈絡更加清晰,即讓人一眼望去,就能很容易地分辨出界面(View)應該寫在哪裏,程序邏輯(Controller)應該寫在哪裏,最終使維護和擴展代碼變得更加容易!

其實,重構很簡單,通讀代碼,感受哪邊不太爽,就改那邊吧!(我目前的感覺)

一個良好的代碼應該是能讓人感到舒服的!

附錄:

1)        重構前的代碼Bmi.java:

複製代碼
 1 package com.demo.android.bmi;
 2 
 3 import java.text.DecimalFormat;
 4 
 5 import android.app.Activity;
 6 import android.os.Bundle;
 7 import android.view.View;
 8 import android.view.View.OnClickListener;
 9 import android.widget.Button;
10 import android.widget.EditText;
11 import android.widget.TextView;
12 
13 public class Bmi extends Activity {
14     /** Called when the activity is first created. */
15     @Override
16     public void onCreate(Bundle savedInstanceState) {
17         super.onCreate(savedInstanceState);
18         setContentView(R.layout.main);
19 
20         // Listen for button clicks
21         Button button = (Button) findViewById(R.id.submit);
22         button.setOnClickListener(calcBMI);
23     }
24 
25     private OnClickListener calcBMI = new OnClickListener() {
26         @Override
27         public void onClick(View v) {
28             DecimalFormat nf = new DecimalFormat("0.00");
29             EditText fieldheight = (EditText) findViewById(R.id.height);
30             EditText fieldweight = (EditText) findViewById(R.id.weight);
31 
32             double height = Double.parseDouble(fieldheight.getText().toString()) / 100;
33             double weight = Double.parseDouble(fieldweight.getText().toString());
34             double BMI = weight / (height * height);
35 
36             TextView result = (TextView) findViewById(R.id.result);
37             result.setText("Your BMI is " + nf.format(BMI));
38 
39             // Give health advice
40             TextView fieldsuggest = (TextView) findViewById(R.id.suggest);
41             if (BMI > 25) {
42                 fieldsuggest.setText(R.string.advice_heavy);
43             } else if (BMI < 20) {
44                 fieldsuggest.setText(R.string.advice_light);
45             } else {
46                 fieldsuggest.setText(R.string.advice_average);
47             }
48         }
49     };
50 }
複製代碼

2)     重構後的代碼Bmi.java:

複製代碼
 1 package com.demo.android.bmi;
 2 
 3 import java.text.DecimalFormat;
 4 
 5 import android.app.Activity;
 6 import android.os.Bundle;
 7 import android.view.View;
 8 import android.widget.Button;
 9 import android.widget.EditText;
10 import android.widget.TextView;
11 
12 public class Bmi extends Activity {
13 
14     private Button button_calc;
15     private EditText field_height;
16     private EditText field_weight;
17     private TextView view_result;
18     private TextView view_suggest;
19 
20     /** Called when the activity is first created. */
21     @Override
22     public void onCreate(Bundle savedInstanceState) {
23         super.onCreate(savedInstanceState);
24         setContentView(R.layout.main);
25 
26         findViews();
27         setListensers();
28     }
29 
30     // 定義
31     private void findViews() {
32         button_calc = (Button) findViewById(R.id.submit);
33         field_height = (EditText) findViewById(R.id.height);
34         field_weight = (EditText) findViewById(R.id.weight);
35         view_result = (TextView) findViewById(R.id.result);
36         view_suggest = (TextView) findViewById(R.id.suggest);
37     }
38 
39     // Listen for button clicks
40     private void setListeners() {
41         calcbutton.setOnClickListener(calcBMI);
42     }
43 
44     private Button.OnClickListener calcBMI = new Button.OnClickListener() {
45         public void onClick(View v) {
46             DecimalFormat nf = new DecimalFormat("0.0");
47             double height = Double.parseDouble(field_height.getText().toString()) / 100;
48             double weight = Double.parseDouble(field_weight.getText().toString());
49             double BMI = weight / (height * height);
50 
51             // Present result
52             view_result.setText(getText(R.string.bmi_result) + nf.format(BMI));
53 
54             // Give health advice
55             if (BMI > 25) {
56                 view_suggest.setText(R.string.advice_heavy);
57             } else if (BMI < 20) {
58                 view_suggest.setText(R.string.advice_light);
59             } else {
60                 view_suggest.setText(R.string.advice_average);
61             }
62         }
63     };
64 }
複製代碼

 

 
 
分類:   Android
相關文章
相關標籤/搜索