Android MVC模式

    【尊重 原创,转载请注明出处 】http://blog.csdn.net/guyuealian/article/details/51172105       前些天看到一篇关于Android MVC模式的技术贴,觉得非常好,所以跟大家分享一下,顺便也说说自己对Android MVC设计模式的见解~~        算来学习Android开发已有2年的历史了,在这2年的学习当中,基本掌握了Android的基础知识。越到后面的学习越感觉困难,一来是自认为android没啥可学的了(自认为的,其实还有很多知识科学),二来网络上的很多框架已经帮我们做了太多的事情了,我们只需要画画UI就可以了,感觉Android开发没有太多的技术含金量。最近闲来无事,开始总结之前学过的知识点,想着是否应该学点其他的东西呢?总不能局限于Android基础知识吧。慢慢的探索发现在大的项目工程中,一个好的框架,好的设计模式,能减少很大的工作量。因此接下来两篇博客来学习一下Android中常用的两种框架设计模式 MVC和MVP。

一、MVC概念

     MVC全名是Model View Controller,是模型(model)-视图(view)-控制器(controller)的缩写,一种软件设计典范,用一种业务逻辑、数据、界面显示分离的方法组织代码,将业务逻辑聚集到一个部件里面,在改进和个性化定制界面及用户交互的同时,不需要重新编写业务逻辑。其中M层处理数据,业务逻辑等;V层处理界面的显示结果;C层起到桥梁的作用,来控制V层和M层通信以此来达到分离视图显示和业务逻辑层。说了这么多,听着感觉很抽象,废话不多说,我们来看看MVC在Android开发中是怎么应用的吧!


二、MVC for Android

 在Android开发中,比较流行的开发框架模式采用的是MVC框架模式,采用MVC模式的好处是便于UI界面部分的显示和业务逻辑,数据处理分开。那么Android项目中哪些代码来充当M,V,C角色呢?

   M模型层:适合做一些业务逻辑处理,比如数据库存取操作,网络操作,复杂的算法,耗时的任务等都在model层处理。 

   V视图层:应用层中处理数据显示的部分,XML布局可以视为V层,显示Model层的数据结果。 

    C控制层:在Android中,Activity处理用户交互问题,因此可以认为Activity是控制器,Activity读取V视图层的数据(eg.读取当前EditText控件的数据),控制用户输入(eg.EditText控件数据的输入),并向Model发送数据请求(eg.发起网络请求等)。

接下来我们通过一个获取天气预报数据的小项目来解读 MVC for Android。先上一个界面图:


(1)Controller控制器

package com.xjp.androidmvcdemo.controller;import android.app.Dialog;import android.app.ProgressDialog;import android.os.Bundle;import android.support.v7.app.ActionBarActivity;import android.view.View;import android.widget.EditText;import android.widget.TextView;import android.widget.Toast; import com.xjp.androidmvcdemo.R;import com.xjp.androidmvcdemo.entity.Weather;import com.xjp.androidmvcdemo.entity.WeatherInfo;import com.xjp.androidmvcdemo.model.OnWeatherListener;import com.xjp.androidmvcdemo.model.WeatherModel;import com.xjp.androidmvcdemo.model.WeatherModelImpl;  public class MainActivity extends ActionBarActivity implements OnWeatherListener, View.OnClickListener {     private WeatherModel weatherModel;    private Dialog loadingDialog;    private EditText cityNOInput;    private TextView city;    private TextView cityNO;    private TextView temp;    private TextView wd;    private TextView ws;    private TextView sd;    private TextView wse;    private TextView time;    private TextView njd;     @Override    protected void onCreate(Bundle savedInstanceState) {        super.onCreate(savedInstanceState);        setContentView(R.layout.activity_main);        weatherModel = new WeatherModelImpl();        initView();    }     /**     * 初始化View     */    private void initView() {        cityNOInput = findView(R.id.et_city_no);        city = findView(R.id.tv_city);        cityNO = findView(R.id.tv_city_no);        temp = findView(R.id.tv_temp);        wd = findView(R.id.tv_WD);        ws = findView(R.id.tv_WS);        sd = findView(R.id.tv_SD);        wse = findView(R.id.tv_WSE);        time = findView(R.id.tv_time);        njd = findView(R.id.tv_njd);        findView(R.id.btn_go).setOnClickListener(this);         loadingDialog = new ProgressDialog(this);        loadingDialog.setTitle(加载天气中...);      }     /**     * 显示结果     *     * @param weather     */    public void displayResult(Weather weather) {        WeatherInfo weatherInfo = weather.getWeatherinfo();        city.setText(weatherInfo.getCity());        cityNO.setText(weatherInfo.getCityid());        temp.setText(weatherInfo.getTemp());        wd.setText(weatherInfo.getWD());        ws.setText(weatherInfo.getWS());        sd.setText(weatherInfo.getSD());        wse.setText(weatherInfo.getWSE());        time.setText(weatherInfo.getTime());        njd.setText(weatherInfo.getNjd());    }     /**     * 隐藏进度对话框     */    public void hideLoadingDialog() {        loadingDialog.dismiss();    }      @Override    public void onClick(View v) {        switch (v.getId()) {            case R.id.btn_go:                loadingDialog.show();                weatherModel.getWeather(cityNOInput.getText().toString().trim(), this);                break;        }    }     @Override    public void onSuccess(Weather weather) {        hideLoadingDialog();        displayResult(weather);    }     @Override    public void onError() {        hideLoadingDialog();        Toast.makeText(this, 获取天气信息失败, Toast.LENGTH_SHORT).show();    }     private  T findView(int id) {        return (T) findViewById(id);    } }

从上面代码可以看到,Activity持有了WeatherModel模型的对象,当用户有点击Button交互的时候,Activity作为Controller控制层读取View视图层EditTextView的数据,然后向Model模型发起数据请求,也就是调用WeatherModel对象的方法 getWeathre()方法。当Model模型处理数据结束后,通过接口OnWeatherListener通知View视图层数据处理完毕,View视图层该更新界面UI了。然后View视图层调用displayResult()方法更新UI。至此,整个MVC框架流程就在Activity中体现出来了。

(2)Model模型

来看看WeatherModelImpl代码实现

package com.xjp.androidmvcdemo.model;/** * Description:请求网络数据接口 * User: xjp * Date: 2015/6/3 * Time: 15:40 */public interface WeatherModel {    void getWeather(String cityNumber, OnWeatherListener listener);} ................  package com.xjp.androidmvcdemo.model; import com.android.volley.Response;import com.android.volley.VolleyError;import com.xjp.androidmvcdemo.entity.Weather;import com.xjp.androidmvcdemo.volley.VolleyRequest; /** * Description:从网络获取天气信息接口实现 * User: xjp * Date: 2015/6/3 * Time: 15:40 */ public class WeatherModelImpl implements WeatherModel {     @Override    public void getWeather(String cityNumber, final OnWeatherListener listener) {         /*数据层操作*/        VolleyRequest.newInstance().newGsonRequest(http://www.weather.com.cn/data/sk/ + cityNumber + .html,                Weather.class, new Response.Listener() {                    @Override                    public void onResponse(Weather weather) {                        if (weather != null) {                            listener.onSuccess(weather);                        } else {                            listener.onError();                        }                    }                }, new Response.ErrorListener() {                    @Override                    public void onErrorResponse(VolleyError error) {                        listener.onError();                    }                });    }}
    利用MVC设计模式,使得这以上代码看出,这里设计了一个WeatherModel模型接口,然后实现了接口WeatherModelImpl类。controller控制器activity调用WeatherModelImpl类中的方法发起网络请求,然后通过实现OnWeatherListener接口来获得网络请求的结果通知View视图层更新UI 。至此,Activity就将View视图显示和Model模型数据处理隔离开了。activity担当contronller完成了model和view之间的协调作用。至于这里为什么不直接设计成类里面的一个getWeather()方法直接请求网络数据?你考虑下这种情况:现在代码中的网络请求是使用Volley框架来实现的,如果哪天老板非要你使用Afinal框架实现网络请求,你怎么解决问题?难道是修改 getWeather()方法的实现? no no no,这样修改不仅破坏了以前的代码,而且还不利于维护, 考虑到以后代码的扩展和维护性,我们选择设计接口的方式来解决着一个问题,我们实现另外一个WeatherModelWithAfinalImpl类,继承自WeatherModel,重写里面的方法,这样不仅保留了以前的WeatherModelImpl类请求网络方式,还增加了WeatherModelWithAfinalImpl类的请求方式。Activity调用代码无需要任何修改。

三、MVC模型总结

    利用MVC设计模式,使得这个天气预报小项目有了很好的可扩展和维护性,当需要改变UI显示的时候,无需修改Contronller(控制器)Activity的代码和Model(模型)WeatherModel模型中的业务逻辑代码,很好的将业务逻辑和界面显示分离。

在Android项目中,业务逻辑、数据处理等担任了Model(模型)角色,XML界面显示等担任了View(视图)角色,Activity担任了Contronller(控制器)角色。contronller(控制器)是一个中间桥梁的作用,通过接口通信来协同 View(视图)和Model(模型)工作,起到了两者之间的通信作用。

什么时候适合使用MVC设计模式?当然一个小的项目且无需频繁修改需求就不用MVC框架来设计了,那样反而觉得代码过度设计,代码臃肿。一般在大的项目中,且业务逻辑处理复杂,页面显示比较多,需要模块化设计的项目使用MVC就有足够的优势了。

在MVC模式中我们发现,其实控制器Activity主要是起到解耦作用,将View视图和Model模型分离,虽然Activity起到交互作用,但是找Activity中有很多关于视图UI的显示代码,因此View视图和Activity控制器并不是完全分离的,也就是说一部分View视图和Contronller控制器Activity是绑定在一个类中的。

四、MVC模型优点:

     (1)耦合性低。所谓耦合性就是模块代码之间的关联程度。利用MVC框架使得View(视图)层和Model(模型)层可以很好的分离,这样就达到了解耦的目的,所以耦合性低,减少模块代码之间的相互影响。

     (2)可扩展性好。由于耦合性低,添加需求,扩展代码就可以减少修改之前的代码,降低bug的出现率。

     (3)模块职责划分明确。主要划分层M,V,C三个模块,利于代码的维护。


如果你觉得该帖子帮到你,还望贵人多多支持,鄙人会再接再厉,继续努力的~

更多相关文章

  1. Android中文 API (31) ―― TimePicker
  2. Android使用Presentation进行双屏开发
  3. Android的源代码结构
  4. Android(安卓)ListView 去除底色、选中色、阴影
  5. 在eclipse中查看android SDK的源代码
  6. Android(安卓)绘制中国地图及热点省份分布
  7. Android的源代码结构
  8. android 2.3 r1 中文 api (58) ―― TabHost
  9. android:shape的使用

随机推荐

  1. 在vs2012中用C#开发Android应用Xamarin环
  2. Android(安卓)material Design 之Coordin
  3. 编译TensorFlow Android(安卓)Camera Dem
  4. android 软件盘相关
  5. Android仿微博、人人Feed详情页吸附导航
  6. Android中四大组件(四大天王)
  7. Chrome不用插件自定义user-agent,模拟手
  8. android actionbar和toolbar的区别
  9. Android获取系统cpu信息,内存,版本,电量等信
  10. Android(安卓)- Vibrator及VibrationEffe