Android的MVC框架

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

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 }
复制代码

 

分类: Android

转载于:https://www.cnblogs.com/fx2008/p/3144695.html

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/462414.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

DVWA-SQL注入

SQL注入解题思路 寻找注入点&#xff0c;可以通过web扫描工具实现通过注入点&#xff0c;尝试得到连接数据库的用户名&#xff0c;数据库名称&#xff0c;权限等信息。猜解关键数据库表极其重要字段与内容。通过获得的用户信息寻找后台进行登录。利用后台上传webshell或一句话木…

void init(void) 分析 ! \linux-1.0\init\main.c

void init(void) {int pid,i;//设置环境信息setup((void *) &drive_info);//打印提示语句sprintf(term, "TERMcon%dx%d", ORIG_VIDEO_COLS, ORIG_VIDEO_LINES);//打开终端1(void) open("/dev/tty1",O_RDWR,0);//拷贝打开的描述字1 &#xff0c;2&#…

查看符号表

objdump -tT libcamera.so转载于:https://www.cnblogs.com/eustoma/archive/2011/11/21/2415805.html

easyui验证:validatebox

2019独角兽企业重金招聘Python工程师标准>>> $.extend($.fn.validatebox.defaults.rules, { eqTrim : {/* 填写名字前面不能有空格&#xff01; */ validator : function(value,param) { var reg new RegExp(param); var falg!reg.test(value); return falg; }, me…

秒懂机器学习---当机器学习遇上决策树....

秒懂机器学习---当机器学习遇上决策树.... 一、总结 一句话总结&#xff1a; 多多看图&#xff0c;图的直观效果很好&#xff0c;很多时候文字实在表达不清 1、决策树&#xff08;Decision Tree&#xff09;中的各个节点表示什么意思&#xff1f; 每一个树节点表示一个属性上的…

void start_kernel(void)分析 ! \linux-1.0\init\main.c

//启动系统内核 //asmlinkage 为通过堆栈传递参数&#xff0c;默认为通过寄存器传递参数。 asmlinkage void start_kernel(void) { /** Interrupts are still disabled. Do necessary setups, then* enable them*///设置中断向量表set_call_gate(&default_ldt,lcall7);//设…

ASP.NET MVC3源码下载

这个貌似是微软官方的源代码 我收藏了 有时间在来研究研究 下载地址&#xff1a;http://files.cnblogs.com/happyyouandme/mvc3%E6%A1%86%E6%9E%B6%E6%BA%90%E7%A0%81.zip 转载于:https://www.cnblogs.com/happyyouandme/archive/2011/11/22/2259108.html

H3C交换机配置学习随笔

1、交换机配置VLAN vlan 创建VLAN: <h3c>system-view [h3c]vlan 10 删除ID为10的vlan&#xff1a;undo vlan 10 注&#xff1a;任何型号的交换机&#xff0c;都支持4096个vlan vlan ID 从0--4095 vlan 0是保留vlan vlan 1是默认vlan display vlan查看本机有多少个vlan&am…

Linux系统目录结构及主要内容

为什么80%的码农都做不了架构师&#xff1f;>>> 文件结构 &#xff1a; /&#xff1a;根目录&#xff0c;所有的目录、文件、设备都在/之下&#xff0c;/就是Linux文件系统的组织者&#xff0c;也是最上级的领导者。 /bin&#xff1a; bin 就是二进制&#xff08;b…

select + 线程池 回应服务器(windows)

//为了支持移植 沿用Ptypes的头文件 #define WIN32 1 #include "ptime.h" #include "pinet.h" #include "ptypes.h" #include "pasync.h"#ifdef WIN32 #pragma comment(lib, "ptypes.lib") #pragma comment(lib, "ws2_…

一个程序员的创业失败教训

原文链接 http://blog.jobbole.com/6752/ 这段经历是悲伤的&#xff0c;也是快乐的&#xff0c;毕竟创业是充满激情的&#xff0c;想着自己以后可以不再给人打工了&#xff0c;可以给自己打工了&#xff0c;一个程序员写了很多年的程序之后&#xff0c;能够有机会给自己写程序&…

学习《深度学习入门:基于Python的理论与实现》高清中文版PDF+源代码

入门神经网络深度学习&#xff0c;推荐学习《深度学习入门&#xff1a;基于Python的理论与实现》&#xff0c;这本书不来虚的&#xff0c;一上来就是手把手教你一步步搭建出一个神经网络&#xff0c;还能把每一步的出处讲明白。理解神经网络&#xff0c;很容易就能入门。 深度学…

每日英文2013.06.19

1.contact /ˈkɑnˌtkt/ v. 接觸;聯繫 (1) Customers may contact any of our location to inquire about car rentals. a.inquire /ɪnˈkwaɪr/ v. to ask someone for information about something b.rental /ˈrent(ə)l/ n. an amount of money that you pay for rentin…

JavaScript 刷新当前页面

1 history.go(0) 2 location.reload() 3 locationlocation 4 location.assign(location) 5 document.execCommand(Refresh) 6 window.navigate(location) 7 location.replace(location) 8 document.URLlocation.href 转载于:https://www.cnblogs.com/SUPERAI/archive/2011/11/2…

学习《PythonWeb开发实战(董伟明)》中文PDF+源代码

python可以用了进行数据分析&#xff0c;也可以进行Web开发&#xff0c;一般会使用django或者flask等进行开发。 国内介绍python web的书有写的不错的&#xff0c;推荐看看《PythonWeb开发实战》 他的定位是进阶读者&#xff0c;介绍了Python web的生态&#xff0c;有些包介绍得…

周鸿祎:在360新员工入职培训上的讲话

这个是周鸿祎给入司360新员工的一段话&#xff0c;不但适合360&#xff0c;也适合所有的公司员工。特此分享。我想给新入职的同事讲一讲我的期望&#xff0c;再提几个建议。我这个人喜欢说真话&#xff0c;不喜欢说漂亮话&#xff0c;因为漂亮话没用。但说真话&#xff0c;大家…

file_exists函数总是返回false

今天在一台开发服务器上遇到一个奇怪的问题&#xff0c;通过WEB方式访问PHP程序 file_exists() 总是返回false&#xff0c;试了很多文件和目录都不行。开始以为是 safe mode 的问题&#xff0c;但是 php.ini 中的safe_mode 选项值是 Off。接着又在命令行以 root 账号执行测试程…

简单的web框架(python)

1、web框架介绍 Web框架&#xff08;Web framework&#xff09;是一种开发框架&#xff0c;用来支持动态网站、网络应用和网络服务的开发。这大多数的web框架提供了一套开发和部署网站的方式&#xff0c;也为web行为提供了一套通用的方法。web框架已经实现了很多功能&#xff0…

set_bit() 等位函数分析! \linux-1.0\linux\include\asm\bitops.h

//将addr的第nr(nr为0-31)位置值置为1; //nr大于31时&#xff0c;把高27的值做为当前地址的偏移&#xff0c;低5位的值为要置为1的位数 extern __inline__ int set_bit(int nr,int * addr) { int mask, retval; addr nr >> 5; //nr大于31时&…

使用面向对象技术创建高级 Web 应用程序

作者&#xff1a; 出处&#xff1a; 使用面向对象技术创建高级 Web 应用程序 来源:开源中国社区 作者:oschina最近&#xff0c;我面试了一位具有5年Web应用开发经验的软件开发人员。她有4年半的JavaScript编程经验&#xff0c;自认为自己具有非常优秀的JavaScript技能&#xff…