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的MVC框架的更多相关文章
- android——根据MVC框架设计的结构
- 简述MVC框架模式以及在你(Android)项目中的应用
标题是阿里电话面试的问题,一直以为自己很清楚MVC模式,结果被问到时,居然没法将MVC和Android中各个组件对应起来,所以,面试肯定挂了,不过面试也是学习的一种方式,可以知道大公司看中什么,以及自 ...
- Android MVC框架模式
MCV model view controller 模型-视图-控制写 M层:适合做一些业务逻辑处理,比如数据库存取操作,网络操作,复杂的算法,耗时的任务等都在model层处理. V层:应用层中处 ...
- Android应用程序MVC框架实例分析
问题提出:如何优雅地分离出应用程序的状态.用户交互和数据表现?如何通过框架体现工程的高性能.高灵活性.高响应性? MVC定义:model.view.controller三者的有机组合,分别表示:模型. ...
- 【腾讯Bugly干货分享】一步一步实现Android的MVP框架
本文来自于腾讯bugly开发者社区,非经作者同意,请勿转载,原文地址:http://dev.qq.com/topic/5799d7844bef22a823b3ad44 内容大纲: Android 开发 ...
- Mithril – 构建杰出 Web 应用的 JS MVC 框架
Mithril 是一个客户端的 Javascript MVC 框架.它是一个工具,使应用程序代码分为数据层,UI 层和粘合层.提供了一个模板引擎与一个虚拟的 DOM diff 实现,用于高性能渲染,支 ...
- Android进阶笔记07:Android之MVC 理解
1. 为什么需要MVC ? 软件中最核心的,最基本的东西是什么? 答:是的,是数据.我们写的所有代码,都是围绕数据的. 围绕着数据的产生.修改等变化,出现了业务逻辑. 围绕着数 ...
- Android之MVC模式的使用
MVC全名是Model View Controller,是模型(model)-视图(view)-控制器(controller)的缩写,一种软件设计典范,用一种业务逻辑.数据.界面显示分离的方法组织代码 ...
- Android之MVC模式
MVC (Model-View-Controller):M是指逻辑模型,V是指视图模型,C则是控制器.一个逻辑模型可以对于多种视图模型,比如一批统计数据 你可以分别用柱状图.饼图来表示.一种视图模型也 ...
随机推荐
- Cortex-M3和Cortex-M4 Fault异常应用之二 ----- Fault处理函数的实现
在项目处于调试期间,Fault处理程序可能只是一个断点指令,调试器遇到这个指令后停止程序的运行.默认情况下,由于非硬Fault被禁能,所有发生的非Fault都会上访成硬Fault,因此只要在硬Faul ...
- Python学习笔记2-Python神奇的语法和格式化输出
先来看一个例子: class Fish: hungry=True def eat(self,food): if food is not None: self.hungry=False class Us ...
- 网易云课堂_程序设计入门-C语言_第四周:循环控制_1素数和
1 素数和(5分) 题目内容: 我们认为2是第一个素数,3是第二个素数,5是第三个素数,依次类推. 现在,给定两个整数n和m,0<n<=m<=200,你的程序要计算第n个素数到第m个 ...
- Ognl中根元素与非根元素的关系
Ognl中根元素与非根元素的关系 根元素:可以理解为全局变量 非根元素:局部变量 从两者获取其属性的方式看: Object obj = Ognl.parseExpression(“[1]”); [1] ...
- Swfit中视图跳转
.跳转到任一UIViewController var sb = UIStoryboard(name: "Main", bundle:nil) var vc = sb.instant ...
- HBASE学习笔记--概述
定义: HBase是一个分布式的.面向列的开源数据库,HBase是Google Bigtable的开源实现,它利用Hadoop HDFS作为其文件存储系统,利用Hadoop MapReduce来处理H ...
- 安卓Xpost框架
http://pcedu.pconline.com.cn/484/4841077_all.html
- 树 -- AVL树
前言 通过之前对二叉查找树的讨论,我们知道在给定节点数目的情况下,二叉树的高度越低,查找所用时间也就越短. 在讨论红黑树的时候,我们说过红黑树并非完全"平衡"的二叉树,只是近似&q ...
- MySQL:ERROR 1217 (23000): Cannot delete or update a parent row: a foreign key constraint fails
MySQL在删除一张表时出现 ERROR 1217 (23000): Cannot delete or update a parent row: a foreign key constraint fa ...
- jQuery1.9.1针对checkbox的调整
在jquery 1.8.x中的版本,我们对于checkbox的选中与不选中操作如下: 判断是否选中 $('#checkbox').prop('checked') 设置选中与不选中状态: $('#che ...