MVC模式(Model-View-Controller)是软件工程中的一种软件架构模式,把软件系统分为三个基本部分:模型(Model)、视图(View)和控制器(Controller)。
模型 - 视图 - 控制器(MVC)设计定义它们之间的相互作用。
- 模型(Model) 用于封装与应用程序的业务逻辑相关的数据以及对数据的处理方法。“ Model”有对数据直接访问的权力,例如对数据库的访问。“Model”不依赖“View”和“Controller”,也就是说, Model不关心它会被如何显示或是如何被操作。
- 视图(View)是界面设计人员进行图形界面设计。能够实现数据有目的的显示(理论上,这不是必需的)。在 View 中一般没有程序上的逻辑。
- 控制器(Controller)起到不同层面间的组织作用,用于控制应用程序的流程。它处理事件并作出响应。“事件”包括用户的行为和数据Model 上的改变。
简单来说:
- View是给用户使用的,也是用户唯一一个能够接触的地方。
- Model是对数据库、网络的数据的处理,是用开发者实现数据交互的地方。
- Controller是View和Model的桥梁。负责转发请求和对请求进行处理。
在Android项目中:
- 业务逻辑,数据处理等担任了Model(模型)角色。
- XML界面显示等担任了View(视图)角色。
- Activity担任了Contronller(控制器)角色。
contronller(控制器)是一个中间桥梁的作用,通过接口通信来协同 View(视图)和Model(模型)工作,起到了两者之间的通信作用。
在维基百科中提到:
- 视图(View)
一般采用XML文件进行界面的描述,使用的时候可以非常方便的引入。当然,如果你对Android了解的比较的多了话,就一定可以想到在Android中也可以使用JavaScript+HTML等的方式作为 View 层,当然这里需要进行Java和JavaScript之间的通信,幸运的是,Android提供了它们之间非常方便的通信实现。 - 控制器(Controller)
Android的控制层的重任通常落在了众多的Activity的肩上,这句话也就暗含了不要在Activity中写代码,要通过Activity交割 Model 业务逻辑层处理,这样做的另外一个原因是Android中的Activity的响应时间是5s,如果耗时的操作放在这里,程序就很容易被回收掉。 - 模型(Model)
对数据库的操作、对网络等的操作都应该在 Model 里面处理,当然对业务计算等操作也是必须放在的该层的。就是应用程序中二进制的数据。
下面是一个MVC的一个简单例子:
public class MainController extends AppCompatActivity implements View.OnClickListener, OnMainListener {
TextView tv1,tv2,tv3,tv4;
Button bt;
MainModel mainModel;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main_controller);
init();
initListener();
}
private void init() {
tv1 = (TextView) findViewById(R.id.view1);
tv2 = (TextView) findViewById(R.id.view2);
tv3 = (TextView) findViewById(R.id.view3);
tv4 = (TextView) findViewById(R.id.view4);
bt = (Button) findViewById(R.id.bt);
mainModel = new MainModel(getApplicationContext());
}
private void initListener() {
bt.setOnClickListener(this);
}
//更新数据
private void updateInfo(Main main) {
tv1.setText(main.getName1());
tv2.setText(main.getName2());
tv3.setText(main.getName3());
tv4.setText(main.getName4());
}
@Override
public void onClick(View v) {
if(v == bt) {
mainModel.getInfo(this);
}
}
@Override
public void onSuccess(Main main) {
updateInfo(main);
Toast.makeText(this, "success", Toast.LENGTH_SHORT).show();
}
@Override
public void onError() {
Toast.makeText(this, "error", Toast.LENGTH_SHORT).show();
}
}
在MainController中,主要实现的是View中控件的初始化和接收Model中传来的数据并更新View的数据。
Activity作为Controller控制层读取View视图层的控件textView的数据,然后向Model模型发起数据请求,也就是调用MainModel对象的方法 getInfo方法。当Model模型处理数据结束后,通过接口OnMainListener通知View视图层数据处理完毕,View视图层该更新界面UI了。然后View视图层调用updateInfo方法更新UI。至此,整个MVC框架流程就在Activity中体现出来了。
public class MainModel {
private Context context;
private static final String url = "http://keepdoingsport.sinaapp.com/primary.php";
public MainModel(Context context) {
this.context = context;
}
public void getInfo(final OnMainListener listener) {
RequestQueue queue = Volley.newRequestQueue(context);
queue.add(new JsonArrayRequest(url, new Response.Listener<JSONArray>() {
@Override
public void onResponse(JSONArray jsonArray) {
try {
JSONObject jsonObject1 = jsonArray.getJSONObject(0);
String name1 = jsonObject1.getString("name");
JSONObject jsonObject2 = jsonArray.getJSONObject(1);
String name2 = jsonObject2.getString("name");
JSONObject jsonObject3 = jsonArray.getJSONObject(2);
String name3 = jsonObject3.getString("name");
JSONObject jsonObject4 = jsonArray.getJSONObject(3);
String name4 = jsonObject4.getString("name");
Main main = new Main(name1, name2, name3, name4);
if (main != null){
listener.onSuccess(main);
}else {
listener.onError();
}
} catch (JSONException e) {
e.printStackTrace();
}
}
}, new Response.ErrorListener() {
@Override
public void onErrorResponse(VolleyError volleyError) {
}
}));
}
}
在MainModel中,使用了Volley读取服务器数据,并通过OnMainListener来通知View更新UI。至此,Activity就将View视图显示和Model模型数据处理隔离开了。activity担当contronller完成了model和view之间的协调作用。
下面是xml文件:
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
android:paddingLeft="@dimen/activity_horizontal_margin"
android:paddingRight="@dimen/activity_horizontal_margin"
android:paddingTop="@dimen/activity_vertical_margin"
android:paddingBottom="@dimen/activity_vertical_margin"
tools:context="com.example.fragmentdemo.MVCDeom.MainController">
<TextView
android:id="@+id/view1"
android:text="hello_world1"
android:layout_width="match_parent"
android:layout_height="wrap_content" />
<TextView
android:id="@+id/view2"
android:text="hello_world2"
android:layout_width="match_parent"
android:layout_height="wrap_content" />
<TextView
android:id="@+id/view3"
android:text="hello_world3"
android:layout_width="match_parent"
android:layout_height="wrap_content" />
<TextView
android:id="@+id/view4"
android:text="hello_world4"
android:layout_width="match_parent"
android:layout_height="wrap_content" />
<Button
android:id="@+id/bt"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:gravity="center"
android:text="change"/>
</LinearLayout>
下面是运行的效果图:
当点击Button时数据便发生改变:
MVC的优点:
(1)耦合性低。所谓耦合性就是模块代码之间的关联程度。利用MVC框架使得View(视图)层和Model(模型)层可以很好的分离,这样就达到了解耦的目的,所以耦合性低,减少模块代码之间的相互影响。
(2)可扩展性好。由于耦合性低,添加需求,扩展代码就可以减少修改之前的代码,降低bug的出现率。
(3)模块职责划分明确。主要划分层M,V,C三个模块,利于代码的维护。