MVC设计思想

Posted Java面试集合

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了MVC设计思想相关的知识,希望对你有一定的参考价值。


 1. 为什么需要MVC ? 

软件中最核心的,最基本的东西是什么? 

答:是的,是数据。我们写的所有代码,都是围绕数据的。

     围绕着数据的产生、修改等变化,出现了业务逻辑

     围绕着数据的显示,出现了不同的界面技术没有很好设计的代码,常常就会出现数据层(持久层)和业务逻辑层还有界面代码耦合的情况。ORM等框架,解耦合了业务逻辑和数据之间的耦合,业务逻辑不再关心底层数据如何存储和读取。所有数据呈现给业务逻辑层的就是一个个的对象。MVC,  MVP, MMVM用来解决业务逻辑和视图之间的耦合

2. MVC

      MVC全名是Model View Controller,是模型(model)-视图(view)-控制器(controller)的缩写,一种软件设计典范,用一种业务逻辑、数据、界面显示分离的方法组织代码,将业务逻辑聚集到一个部件里面,在改进和个性化定制界面及用户交互的同时,不需要重新编写业务逻辑。其中M层处理数据,业务逻辑等;V层处理界面的显示结果;C层起到桥梁的作用,来控制V层和M层通信以此来达到分离视图显示View业务逻辑层Model。MVC的目的是将M和V的实现代码分离,从而使同一个程序可以使用不同的表现形式。比如一批统计数据可以分别用柱状图、饼图来表示。C存在的目的则是确保M和V的同步,一旦M改变,V应该同步更新。

说了这么多,听着感觉很抽象,废话不多说,我们来看看MVC在android开发中是怎么应用的吧!

MVC设计思想

 

 

 

MVC设计思想

 

     

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

  Model在values目录下通过xml文件格式生成,也可以通过硬编码的方式直接Java代码生成。View和Model是通过桥梁Adapter来连接起来。

    • View层:应用层中处理数据显示的部分,XML布局可以视为V层,显示Model层的数据结果。 View是软件应用传送给用户的一个反馈结果。它代表软件应用中的图形展示、声音播放、触觉反馈等职责。视图的根节点是应用程序的自身窗口。比如,视频播放器中可能包含当前播放的画面,这个画面就是一个视图。另一个视图组件可能是该视频的文字标题。再一个就是一些播放按键,比如:Stop、Start、Pause等按钮。

 

 

总而言之,MVC框架如下

  • View 是应用程序中负责生成用户界面的部分。也是在整个mvc架构中用户唯一可以看到的一层接收用户的输入显示处理结果

  • Controller 是根据用户的输入,控制用户界面数据显示及更新model对象状态的部分,控制器更重要的一种导航功能,想用用户出发的相关事件,交给Model处理

  • Model 应用程序的主体部分,所有的业务逻辑都应该写在该层

 

 

 

-----------------------------------------------MVC典型例子的实现ListView-----------------------------------------

Android中最典型MVC是ListView,要显示的数据是Model,界面中的ListView是View,控制数据怎样在ListView中显示是Controller,这里可以理解Activity是Controller

 

 • 通过硬编码的方式直接Java代码生成方式,这里直接在注释讲解:

[java] view plain copy

  1. public class ArrayAdapterActivity extends Activity {  

  2.     @Override  

  3.     protected void onCreate(Bundle savedInstanceState) {  

  4.         super.onCreate(savedInstanceState);  

  5.           

  6.        ListView listView = new ListView(this);  

  7.           

  8.         ArrayAdapter<String> adapter = new ArrayAdapter<String>(this, android.R.layout.simple_expandable_list_item_1, getData());  

  9.          

  10.         listView.setAdapter(adapter);  

  11.         setContentView(listView);  

  12.         // 点击事件,Controller负责  

  13.         listView.setOnItemClickListener(new OnItemClickListener() {  

  14.             @Override  

  15.            public void onItemClick(AdapterView<?> parent, View view, int position, long id) {  

  16.                 // position是从0开始的,获取点击item的内容  

  17.                 Toast.makeText(ArrayAdapterActivity.this, getData().get(position), Toast.LENGTH_SHORT).show();  

  18.             }  

  19.         });  

  20.     }  

  21.     // 要显示的数据Model,通过硬编码的方式直接Java代码生成  

  22.     private List<String> getData() {  

  23.         List<String> data = new ArrayList<String>();  

  24.         data.add("a");  

  25.         data.add("b");  

  26.         data.add("c");  

  27.         data.add("d");  

  28.         return data;  

  29.     }  

  30. }  


• 视图View和模型Model取资源文件方式:

先在res/layout文件夹下创建文件activity_arrayadapter.xml,可以看出只包含一个ListView,即视图View

[java] view plain copy

  1.  1 <?xml version="1.0" encoding="utf-8"?>  

  2.  2 <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"  

  3.  3     android:layout_width="fill_parent"  

  4.  4     android:layout_height="fill_parent"  

  5.  5     android:orientation="vertical" >  

  6.  6     <ListView  

  7.  7         android:id="@+id/listview"  

  8.  8         android:layout_width="fill_parent"  

  9.  9         android:layout_height="fill_parent"  

  10. 10         android:drawSelectorOnTop="false" />  

  11. 11 </LinearLayout>  



在res/values文件夹下的strings.xml添加一个字符数组,及模型Model

[html] view plain copy

  1. <?xml version="1.0" encoding="utf-8"?>  

  2. <resources>  

  3. 3     <string-array name="good">  

  4. 4             <item>a</item>  

  5. 5             <item>b</item>  

  6. 6             <item>c</item>  

  7. 7             <item>d</item>  

  8. 8     </string-array>  

  9. </resources>  



Activity代码,在注释中讲解MVC模型使用:

[java] view plain copy

  1.  1 public class ArrayAdapterActivity2 extends Activity {  

  2.  2     @Override  

  3.  3     protected void onCreate(Bundle savedInstanceState) {  

  4.  4         super.onCreate(savedInstanceState);  

  5.  5         setContentView(R.layout.activity_arrayadapter);  

  6.  6           

  7.  7         ListView listView = (ListView) findViewById(R.id.listview);  

  8.  8           

  9.  9         ArrayAdapter<String> adapter = new ArrayAdapter<String>(this, android.R.layout.simple_expandable_list_item_1, getData());  

  10. 10           

  11. 11         listView.setAdapter(adapter);  

  12. 12         // 点击事件,Controller负责  

  13. 13         listView.setOnItemClickListener(new OnItemClickListener() {  

  14. 14             @Override  

  15. 15             public void onItemClick(AdapterView<?> parent, View view, int position, long id) {  

  16. 16                 // position是从0开始的,获取点击item的内容  

  17. 17                 Toast.makeText(ArrayAdapterActivity2.this, getData().get(position), Toast.LENGTH_SHORT).show();  

  18. 18             }  

  19. 19         });  

  20. 20     }  

  21. 21     // 要显示的数据Model,Model在values目录下通过xml文件格式生成  

  22. 22     private List<String> getData() {  

  23. 23         List<String> data = new ArrayList<String>();  

  24. 24         Resources res =getResources();  

  25. 25         // 取xml文件格式的字符数组  

  26. 26         String[] good=res.getStringArray(R.array.good);  

  27. 27         for(int i=0;i<good.length;i++){  

  28. 28             data.add(good[i]);  

  29. 29         }  

  30. 30         return data;  

  31. 31     }  

  32. 32 }  



Android的MVC模式要在项目中慢慢理解,这样才能理解透彻并活学活用。

 

 

-----------------------------------------------MVC典型例子之获取天气预报数据-----------------------------------------

先上一个界面图:

MVC设计思想

 

 

  • Controller控制器:

[java] view plain copy

  1.   1 package com.xjp.androidmvcdemo.controller;  

  2.   2    

  3.   3 import android.app.Dialog;  

  4.   4 import android.app.ProgressDialog;  

  5.   5 import android.os.Bundle;  

  6.   6 import android.support.v7.app.ActionBarActivity;  

  7.   7 import android.view.View;  

  8.   8 import android.widget.EditText;  

  9.   9 import android.widget.TextView;  

  10.  10 import android.widget.Toast;  

  11.  11    

  12.  12 import com.xjp.androidmvcdemo.R;  

  13.  13 import com.xjp.androidmvcdemo.entity.Weather;  

  14.  14 import com.xjp.androidmvcdemo.entity.WeatherInfo;  

  15.  15 import com.xjp.androidmvcdemo.model.OnWeatherListener;  

  16.  16 import com.xjp.androidmvcdemo.model.WeatherModel;  

  17.  17 import com.xjp.androidmvcdemo.model.WeatherModelImpl;  

  18.  18    

  19.  19    

  20.  20 public class MainActivity extends ActionBarActivity implements OnWeatherListener, View.OnClickListener {  

  21.  21    

  22.  22     private WeatherModel weatherModel;  

  23.  23     private Dialog loadingDialog;  

  24.  24     private EditText cityNOInput;  

  25.  25     private TextView city;  

  26.  26     private TextView cityNO;  

  27.  27     private TextView temp;  

  28.  28     private TextView wd;  

  29.  29     private TextView ws;  

  30.  30     private TextView sd;  

  31.  31     private TextView wse;  

  32.  32     private TextView time;  

  33.  33     private TextView njd;  

  34.  34    

  35.  35     @Override  

  36.  36     protected void onCreate(Bundle savedInstanceState) {  

  37.  37         super.onCreate(savedInstanceState);  

  38.  38         setContentView(R.layout.activity_main);  

  39.  39         weatherModel = new WeatherModelImpl();  

  40.  40         initView();  

  41.  41     }  

  42.  42    

  43.  43     /** 

  44.  44      * 初始化View 

  45.  45      */  

  46.  46     private void initView() {  

  47.  47         cityNOInput = findView(R.id.et_city_no);  

  48.  48         city = findView(R.id.tv_city);  

  49.  49         cityNO = findView(R.id.tv_city_no);  

  50.  50         temp = findView(R.id.tv_temp);  

  51.  51         wd = findView(R.id.tv_WD);  

  52.  52         ws = findView(R.id.tv_WS);  

  53.  53         sd = findView(R.id.tv_SD);  

  54.  54         wse = findView(R.id.tv_WSE);  

  55.  55         time = findView(R.id.tv_time);  

  56.  56         njd = findView(R.id.tv_njd);  

  57.  57         findView(R.id.btn_go).setOnClickListener(this);  

  58.  58    

  59.  59         loadingDialog = new ProgressDialog(this);  

  60.  60         loadingDialog.setTitle(加载天气中...);  

  61.  61    

  62.  62    

  63.  63     }  

  64.  64    

  65.  65     /** 

  66.  66      * 显示结果 

  67.  67      * 

  68.  68      * @param weather 

  69.  69      */  

  70.  70     public void displayResult(Weather weather) {  

  71.  71         WeatherInfo weatherInfo = weather.getWeatherinfo();  

  72.  72         city.setText(weatherInfo.getCity());  

  73.  73         cityNO.setText(weatherInfo.getCityid());  

  74.  74         temp.setText(weatherInfo.getTemp());  

  75.  75         wd.setText(weatherInfo.getWD());  

  76.  76         ws.setText(weatherInfo.getWS());  

  77.  77         sd.setText(weatherInfo.getSD());  

  78.  78         wse.setText(weatherInfo.getWSE());  

  79.  79         time.setText(weatherInfo.getTime());  

  80.  80         njd.setText(weatherInfo.getNjd());  

  81.  81     }  

  82.  82    

  83.  83     /** 

  84.  84      * 隐藏进度对话框 

  85.  85      */  

  86.  86     public void hideLoadingDialog() {  

  87.  87         loadingDialog.dismiss();  

  88.  88     }  

  89.  89    

  90.  90    

  91.  91     @Override  

  92.  92     public void onClick(View v) {  

  93.  93         switch (v.getId()) {  

  94.  94             case R.id.btn_go:  

  95.  95                 loadingDialog.show();  

  96.  96                 weatherModel.getWeather(cityNOInput.getText().toString().trim(), this);  

  97.  97                 break;  

  98.  98         }  

  99.  99     }  

  100. 100    

  101. 101     @Override  

  102. 102     public void onSuccess(Weather weather) {  

  103. 103         hideLoadingDialog();  

  104. 104         displayResult(weather);  

  105. 105     }  

  106. 106    

  107. 107     @Override  

  108. 108     public void onError() {  

  109. 109         hideLoadingDialog();  

  110. 110         Toast.makeText(this, 获取天气信息失败, Toast.LENGTH_SHORT).show();  

  111. 111     }  

  112. 112    

  113. 113     private <t extends="" view=""> T findView(int id) {  

  114. 114         return (T) findViewById(id);  

  115. 115     }  

  116. 116    

  117. 117 }  



  • Model模型

来看看WeatherModelImpl代码实现:

[java] view plain copy

  1.  1 package com.xjp.androidmvcdemo.model;  

  2.  2    

  3.  3 /** 

  4.  4  * Description:请求网络数据接口 

  5.  5  * User: xjp 

  6.  6  * Date: 2015/6/3 

  7.  7  * Time: 15:40 

  8.  8  */  

  9.  9    

  10. 10 public interface WeatherModel {  

  11. 11     void getWeather(String cityNumber, OnWeatherListener listener);  

  12. 12 }  

  13. 13    

  14. 14 ................  

  15. 15    

  16. 16    

  17. 17 package com.xjp.androidmvcdemo.model;  

  18. 18    

  19. 19 import com.android.volley.Response;  

  20. 20 import com.android.volley.VolleyError;  

  21. 21 import com.xjp.androidmvcdemo.entity.Weather;  

  22. 22 import com.xjp.androidmvcdemo.volley.VolleyRequest;  

  23. 23    

  24. 24 /** 

  25. 25  * Description:从网络获取天气信息接口实现 

  26. 26  * User: xjp 

  27. 27  * Date: 2015/6/3 

  28. 28  * Time: 15:40 

  29. 29  */  

  30. 30    

  31. 31 public class WeatherModelImpl implements WeatherModel {  

  32. 32    

  33. 33    @Override  

  34. 34     public void getWeather(String cityNumber, final OnWeatherListener listener) {  

  35. 35    

  36. 36         /*数据层操作*/  

  37. 37         VolleyRequest.newInstance().newGsonRequest(http://www.weather.com.cn/data/sk/ + cityNumber + .html,  

  38. 38                 Weather.classnew Response.Listener<weather>() {  

  39. 39                     @Override  

  40. 40                     public void onResponse(Weather weather) {  

  41. 41                         if (weather != null) {  

  42. 42                             listener.onSuccess(weather);  

  43. 43                         } else {  

  44. 44                             listener.onError();  

  45. 45                         }  

  46. 46                     }  

  47. 47                 }, new Response.ErrorListener() {  

  48. 48                     @Override  

  49. 49                     public void onErrorResponse(VolleyError error) {  

  50. 50                         listener.onError();  

  51. 51                     }  

  52. 52                 });  

  53. 53     }  

  54. 54 }  



  以上代码看出,这里设计了一个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的优点

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

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

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

长按二维码识别关注我们  




以上是关于MVC设计思想的主要内容,如果未能解决你的问题,请参考以下文章

MVC 设计模式

从MVC框架看MVC架构的设计

从MVC框架看MVC架构的设计

MVC设计模式

MVC设计模式

MVC设计模式