zoukankan      html  css  js  c++  java
  • Android的MVC框架 [转]

     Android的MVC框架 

    MVC是当前比较流行的框架,随便Google下,就可以发现几乎所有的应用程序开发中都采用了MVC框架,例如:.NET,Java Spring,Java Struts,PHP 。那么MVC到底是什么,为什么被广泛使用? 

    简要说明下,什么是MVC。MVC (Model-View-Controller):M是指逻辑模型,V是指视图模型,C则是控制器。一个逻辑模型可以对于多种视图模型,比如一批统计数据你可以分别用柱状图、饼图来表示。一种视图模型也可以对于多种逻辑模型。使用MVC的目的是将M和V的实现代码分离,从而使同一个程序可以使用不同的表现形式,而C存在的目的则是确保M和V的同步,一旦M改变,V应该同步更新,这与《设计模式》中的观察者模式是完全一样。具体详细的解析,可以去阅读百度知道中介绍的什么是MVC? 

    采用MVC到底有什么好处?从用户的角度出发,用户可以根据自己的需求,选择自己合适的浏览数据的方式。比如说,对于一篇在线文档,用户可以选择以HTML网页的方式阅读,也可以选择以pdf的方式阅读。从开发者的角度,MVC把应用程序的逻辑层与界面是完全分开的,最大的好处是:界面设计人员可以直接参与到界面开发,程序员就可以把精力放在逻辑层上。而不是像以前那样,设计人员把所有的材料交给开发人员,由开发人员来实现界面。在VS 2008开发工具中设计人员就可以直接通过Silverlight来开发界面,在Eclipes工具中开发Android采用了更加简单的方法,设计人员在DroidDraw中设计界面,以XML方式保存,在Eclipes中直接打开就可以看到设计人员设计的界面。 

    Android中界面部分也采用了当前比较流行的MVC框架,在Android中M就是应用程序中二进制的数据,V就是用户的界面。Android的界面直接采用XML文件保存的,界面开发变的很方便。在Android中C也是很简单的,一个Activity可以有多个界面,只需要将视图的ID传递到setContentView(),就指定了以哪个视图模型显示数据。 

    在Android SDK中的数据绑定,也都是采用了与MVC框架类似的方法来显示数据。在控制层上将数据按照视图模型的要求(也就是Android SDK中的Adapter)封装就可以直接在视图模型上显示了,从而实现了数据绑定。比如显示Cursor中所有数据的ListActivity,其视图层就是一个ListView,将数据封装为ListAdapter,并传递给ListView,数据就在ListView中现实。 

    目前Android中采用的MVC框架还是比较简单的,在未来还会不断完善。Android SDK如果要实现类似与MFC中视图/文档模型(View/Document Model),恐怕还需要等待一些时日,让我们拭目以待吧。  

    MVC进行重构 

    感谢:http://code.google.com/p/androidbmi/wiki/BmiRefactor写的非常的好,通俗易懂而又不显啰嗦,真是恰到好处啊! 

    本文仅以代码说话,主要是方便自己回想这样重构的好处,记录一下自己重构过程中的思路逻辑,更多的文字介绍请看前面那个链接! 

    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 }
  • 相关阅读:
    spring与springmvc父子容器
    spring容器BeanFactory简单例子
    spring整体架构
    css中".",",",“~”和“>”符号的意义
    CSS中的块级元素与行级元素
    java反射和动态代理
    thymeleaf的fragment例子
    编写一个简单的 JDBC 程序
    http://localhost/ 或 http://127.0.0.1/ 报错:HTTP 404 的解决办法
    教你如何清除 MyEclipse/Eclipse 中 Web Browser 和 Switch Workspace 的历史记录
  • 原文地址:https://www.cnblogs.com/wanghafan/p/2600786.html
Copyright © 2011-2022 走看看