MCV  model view controller  模型-视图-控制写

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

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

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

首先来看一下MVC模式的例子,调用网络接口————藏头诗生成接口

xml布局如下:

     xmlns:tools="http://schemas.android.com/tools"
android:id="@+id/activity_main"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
tools:context="com.example.lesson_mvc_cangtoushi.ui.MainActivity"> <RadioGroup
android:id="@+id/rg_57"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="horizontal"> <RadioButton
android:id="@+id/rb_5"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1"
android:gravity="center"
android:text="五言诗" /> <RadioButton
android:id="@+id/rb_7"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1"
android:gravity="center"
android:text="七言诗" />
</RadioGroup> <RadioGroup
android:id="@+id/rg_ct"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="horizontal"> <RadioButton
android:id="@+id/rb_ct"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1"
android:gravity="center"
android:text="藏头" /> <RadioButton
android:id="@+id/rb_cw"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1"
android:gravity="center"
android:text="藏尾" /> <RadioButton
android:id="@+id/rb_cz"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1"
android:gravity="center"
android:text="藏中" /> <RadioButton
android:id="@+id/rb_dz"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1"
android:gravity="center"
android:text="递增" /> <RadioButton
android:id="@+id/rb_dj"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1"
android:gravity="center"
android:text="递减"/> </RadioGroup> <RadioGroup
android:id="@+id/rg_yy"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="horizontal"> <RadioButton
android:id="@+id/rb_1y"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1"
android:gravity="center"
android:text="双句一押" /> <RadioButton
android:id="@+id/rb_2y"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1"
android:gravity="center"
android:text="双句押韵" /> <RadioButton
android:id="@+id/rb_3y"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1"
android:gravity="center"
android:text="一三四押" />
</RadioGroup>
<EditText
android:id="@+id/et_key"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:hint="请输入藏头诗"/>
<Button
android:id="@+id/btn_submit"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="提交"/> <ScrollView
android:layout_width="match_parent"
android:layout_height="match_parent">
<TextView
android:id="@+id/tv_show"
android:layout_width="match_parent"
android:layout_height="match_parent" />
</ScrollView> </LinearLayout>

activity_main.xml

java代码目录结构:

首先需要一个bean,藏头诗对象原型

 public class CangTouShiBean {

     /**
* showapi_res_code : 0
* showapi_res_error :
* showapi_res_body : {"ret_code":0,"list":["北风勇士马,晚水独芙蓉。吾将宝非宝,英雄徒自强。","朝骑五花马,太华三芙蓉。吾将宝非宝,天子贵文强。","请歌牵白马,菡萏金芙蓉。大位天下宝,自从冒顿强。","青丝系五马,秀出九芙蓉。迈德惟家宝,日来知自强。","北买党项马,美女夸芙蓉。河宗来献宝,十年思自强。","青丝系五马,大嫂采芙蓉。药妙灵仙宝,不独有文强。"]}
*/ private int showapi_res_code;
private String showapi_res_error;
private ShowapiResBodyBean showapi_res_body; @Override
public String toString() {
return "CangTouShiBean{" +
"showapi_res_code=" + showapi_res_code +
", showapi_res_error='" + showapi_res_error + '\'' +
", showapi_res_body=" + showapi_res_body +
'}';
} public int getShowapi_res_code() {
return showapi_res_code;
} public void setShowapi_res_code(int showapi_res_code) {
this.showapi_res_code = showapi_res_code;
} public String getShowapi_res_error() {
return showapi_res_error;
} public void setShowapi_res_error(String showapi_res_error) {
this.showapi_res_error = showapi_res_error;
} public ShowapiResBodyBean getShowapi_res_body() {
return showapi_res_body;
} public void setShowapi_res_body(ShowapiResBodyBean showapi_res_body) {
this.showapi_res_body = showapi_res_body;
} public static class ShowapiResBodyBean {
/**
* ret_code : 0
* list : ["北风勇士马,晚水独芙蓉。吾将宝非宝,英雄徒自强。","朝骑五花马,太华三芙蓉。吾将宝非宝,天子贵文强。","请歌牵白马,菡萏金芙蓉。大位天下宝,自从冒顿强。","青丝系五马,秀出九芙蓉。迈德惟家宝,日来知自强。","北买党项马,美女夸芙蓉。河宗来献宝,十年思自强。","青丝系五马,大嫂采芙蓉。药妙灵仙宝,不独有文强。"]
*/ private int ret_code;
private List<String> list; @Override
public String toString() {
return "ShowapiResBodyBean{" +
"ret_code=" + ret_code +
", list=" + list +
'}';
} public int getRet_code() {
return ret_code;
} public void setRet_code(int ret_code) {
this.ret_code = ret_code;
} public List<String> getList() {
return list;
} public void setList(List<String> list) {
this.list = list;
}
}
}

CangTouShiBean.java

其次实藏头诗的接口,根据藏头诗的类型参数,请求数据,使用回调接口返回数据

 public interface BeanCallback<T> {

     void onError(String msg);
void onSuccess(T t);
}

BeanCallback.java

 public interface ICangTouShi {
//请求数据,需要有变化的参数
void doRequest(String num, String type, String yayuntype, String key,BeanCallback<CangTouShiBean> callback); }

ICangTouShi.java

藏头诗的model实现藏头诗的接口,并实现请求数据的方法

 public class CangTouShiModel implements ICangTouShi{
@Override
public void doRequest(String num, String type, String yayuntype, String key, final BeanCallback<CangTouShiBean> callback) { //请求数据
//使用OkHttp OkHttpClient client = new OkHttpClient(); RequestBody body = new FormBody.Builder()
.add("showapi_appid","27306")
.add("showapi_sign","150e9206e7f542bab4affe49d73cb920")
.add("num",num)
.add("type",type)
.add("yayuntype",yayuntype)
.add("key",key).build(); Request request = new Request.Builder()
.post(body)
.url("http://route.showapi.com/950-1").build();
Call call = client.newCall(request);
//异步请求,子线程
call.enqueue(new Callback() {
@Override
public void onFailure(Call call, IOException e) {
Log.e("TAG","-----------"+e.getMessage());
callback.onError(e.getMessage());
} @Override
public void onResponse(Call call, Response response) throws IOException {
String json = response.body().string();
Gson gson = new Gson();
CangTouShiBean bean = gson.fromJson(json, CangTouShiBean.class);
callback.onSuccess(bean);
}
}); } }

CangTouShiModel.java

View层即Activity中,加载视图

 public class MainActivity extends AppCompatActivity {

     //逻辑判断,UI操作

     RadioGroup rg_57,rg_ct,rg_yy;
EditText et_key;
Button btn_submit;
TextView tv_show; @Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
initView();
registerListener();
} private void registerListener() {
//逻辑控制
//实际上就只要监听提交按钮即可,因为其他的按钮只是获取数据,不需要按下后立即更改UI btn_submit.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
String key = et_key.getText().toString();
if(TextUtils.isEmpty(key)){
Toast.makeText(MainActivity.this,"key不能为空",Toast.LENGTH_SHORT).show();
return;
}
String num = rg_57.getCheckedRadioButtonId()==R.id.rb_5?"5":"7";
String type = null;
switch (rg_ct.getCheckedRadioButtonId()){
case R.id.rb_ct:
type = "1";
break;
case R.id.rb_cw:
type = "2";
break;
case R.id.rb_cz:
type = "3";
break;
case R.id.rb_dz:
type = "4";
break;
case R.id.rb_dj:
type = "5";
break;
}
String yy = null;
switch (rg_yy.getCheckedRadioButtonId()){
case R.id.rb_1y:
yy="1";
break;
case R.id.rb_2y:
yy="2";
break;
case R.id.rb_3y:
yy="3";
break;
} final ProgressDialog dialog = new ProgressDialog(MainActivity.this);
dialog.setTitle("提示");
dialog.setMessage("开始请求");
dialog.show(); //请求数据
CangTouShiModel model = new CangTouShiModel();
//OkHttp的异步请求,在子线程中
model.doRequest(num, type, yy, key, new BeanCallback<CangTouShiBean>() {
@Override
public void onError(String msg) {
runOnUiThread(new Runnable() {
@Override
public void run() {
dialog.dismiss();
Toast.makeText(MainActivity.this,"msg",Toast.LENGTH_SHORT).show(); }
});
} @Override
public void onSuccess(final CangTouShiBean bean) {
runOnUiThread(new Runnable() {
@Override
public void run() {
dialog.dismiss();
List<String> list = bean.getShowapi_res_body().getList();
tv_show.setText("");
for (String s : list) {
tv_show.append(s+"\n");
} }
}); }
});
}
}); } private void initView() {
rg_57 = (RadioGroup) findViewById(R.id.rg_57);
rg_57.check(R.id.rb_5);
rg_ct = (RadioGroup) findViewById(R.id.rg_ct);
rg_ct.check(R.id.rb_ct);
rg_yy = (RadioGroup) findViewById(R.id.rg_yy);
rg_yy.check(R.id.rb_1y);
et_key = (EditText) findViewById(R.id.et_key);
btn_submit = (Button) findViewById(R.id.btn_submit);
tv_show = (TextView) findViewById(R.id.tv_show); } }

MainActivity.java

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

MVC的优点:

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

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

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

Android MVC框架模式的更多相关文章

  1. 简述MVC框架模式以及在你(Android)项目中的应用

    标题是阿里电话面试的问题,一直以为自己很清楚MVC模式,结果被问到时,居然没法将MVC和Android中各个组件对应起来,所以,面试肯定挂了,不过面试也是学习的一种方式,可以知道大公司看中什么,以及自 ...

  2. Android MVP框架模式

    结合前一篇MVC框架模式 为了更好地细分视图(View)与模型(Model)的功能,让View专注于处理数据的可视化以及与用户的交互,同时让Model只关系数据的处理,基于MVC概念的MVP(Mode ...

  3. MVC框架模式技术实例(用到隐藏帧、json、仿Ajax、Dom4j、jstl、el等)

    前言: 刚刚学完了MVC,根据自己的感悟和理解写了一个小项目. 完全按照MVC模式,后面有一个MVC的理解示意图. 用MVC模式重新完成了联系人的管理系统: 用户需求: 多用户系统,提供用户注册.登录 ...

  4. MVC框架模式和Javaweb经典三层架构

    一.MVC设计模式 1.MVC的概念 首先我们需要知道MVC模式并不是javaweb项目中独有的,MVC是一种软件工程中的一种软件架构模式,把软件系统分为三个基本部分:模型(Model).视图(Vie ...

  5. 简单的JAVA MVC框架模式--Java-servlet-JavaBean

    MVC全名是Model View Controller,是模型(model)-视图(view)-控制器(controller)的缩写,一种软件设计典范,用一种业务逻辑.数据.界面显示分离的方法组织代码 ...

  6. 初次了解MVC框架模式

    MVC框架:即Model.View.Controller即模型.视图.控制器. View层是界面,Model层是业务逻辑,Controller层用来调度View层和Model层,将显示界面和业务逻辑合 ...

  7. Android基础——框架模式MVC在安卓中的实践

    本篇文章包含以下内容: MVC的介绍 MVC的实践 MVC的介绍 MVC (Model View Controller),是模型(model)视图(view)控制器(controller)的缩写,一种 ...

  8. mvc框架模式

    首先分为3个板块 路由的api相当于一个域名. 根据当前地址在执行路由里的代码; 逻辑层: 书写业务逻辑的都代码都放在controller层 数据处理层: model 写数据的增删改查方法,导出一般供 ...

  9. [转]框架模式 MVC 在Android中的使用

    算来学习Android开发已有2年的历史了,在这2年的学习当中,基本掌握了Android的基础知识.越到后面的学习越感觉困难,一来是自认为android没啥可学的了(自认为的,其实还有很多知识科学), ...

随机推荐

  1. placeholder调整颜色

    placeholder需要设定以下样式: ::-webkit-input-placeholder { /* WebKit browsers */ color: #999; } :-moz-placeh ...

  2. nuc970连接jlink进行单步调试的设置

    在 USB mode 下, 先跟 NuWriter 接上, 然后用以下的设定. 按 Keil 的 debug (不是 download to flash)就可以接上了.

  3. html中的空格可以用什么代替

    半角空格用 代替,全角的空格可以直接在网页里生效. 打全角空格的两种方法:1.智能ABC按v1,选择第一个2.按shift+空格切换输入法的“半.全角”状态为全角再按空格

  4. 转:PHP 5.4中的traits

    原文来自于:http://www.cnblogs.com/thinksasa/archive/2013/05/16/3081247.html PHP 5.4中的traits,是新引入的特性,中文还真不 ...

  5. Unity 网络斗地主 判断牌的类型

    Unity 网络斗地主  牌的类型 web版本演示地址:   http://www.dreamhome666.com/Desktop.html 在上个版本中,下面的角色在牌的后面,可以将角色做为一个P ...

  6. QMapControl介绍

    QMapControl是Qt开发的基于LGPL协议开源的显示OpenStreetMap(下简称osm)Tile数据和基于wms-server服务的数据,这里做简单介绍并列出相关资源. QMapCont ...

  7. 如何用正则匹配后缀名不为.jpg, .css, .js, .html, .htm, .png的文件

    有网友碰到过这样的问题:如何用正则匹配后缀名不为.jpg, .css, .js, .html, .htm, .png的文件,问题详细内容为: 如何用正则匹配后缀名不为.jpg, .css, .js, ...

  8. open和fopen的区别(转)

    转载自:http://www.cnblogs.com/joeblackzqq/archive/2011/04/11/2013010.html open和fopen的区别: 1.缓冲文件系统缓 冲文件系 ...

  9. splay模板

    点操作: splay树可以一个一个的插入结点,这样的splay树是有序树,结点权值大于左儿子小于右儿子 这样就是点操作 区间操作: 还有就是可以自己建树,这样的splay树就不是按权值的有序树,它不满 ...

  10. (转载)PHP 提示和技巧

    (转载)http://www.111cn.net/phper/21/b4aea31507014a778b18682943db402f.htm 1. 当您在寻找关于某个具体的 PHP 函数的信息时,请转 ...