******再度回头看看安卓的MVC开发模式的总结******
1. 概述
MVC(Model - View - Controller):即 模型 - 视图 - 控制器的简写,一种软件中的设计规范,用一种既有逻辑业务、数据以及界面分离显示的设计模式,按照职责划分,将业务逻辑模块放到一个类里面去,在扩展和定制化和UI交互上,不需要重新对业务模块进行重新编写。
2. 架构及图解
![]() |
Model:即数据层,负责处理业务逻辑,请求数据,监听网络与数据库接口。
View:即界面(UI)层,包括Activity/Fragment,用来显示来源于Model的数据,呈现给用户查看。
Controller:即控制器层,处理业务逻辑的,传递用户的交互和更新Model中的数据。
3. 优缺点
优点:
① 在一定程度上降低了代码之间的耦合性;
② 重用性高;
③ 分工明确,各司所职。
缺点:
① 视图和控制器之间太过于紧密的联系,阻碍了各自的重用。
② 随着界面和业务逻辑的复杂度不断增加,Activity类的职责也不断增加,导致变得庞大臃肿。
③ 改造以适应MVC需要和建立分离的部件的代价很高。
4. 案例说明
请求接口的数据来源于 https://www.avatardata.cn/Docs/Api/5bc6f2a4-927c-415f-80ae-8772b76c8c73
有请求次数的限制,所以需要使用的,可自行注册账号,进行测试使用。
案例①

/**
* 泛型类的回调接口
*
* @param <T>
*/
public interface CallBack<T> {
void onSuccess(T response);
void onError(String error);
}
/**
* 数据模型接口层.
*
* @author luyh
* @version 1.0
* @date 2019/04/08
*/
public interface IAphorismsAModel {
/**
* 请求网络获取数据列表
*
* @param page 页码
* @param rows 一次请求返回多少数据
* @param callBack 回调函数(用来通知View层)
*/
public void getListData(int page, int rows, CallBack callBack);
}
/**
* 数据模型实现层(负责处理数据的加载或者存储).
*
* @author luyh
* @version 1.0
* @date 2019/04/08
*/
public class AphorismsAModelImpl implements IAphorismsAModel {
/**
* 请求网络获取数据列表
*
* @param page 页码
* @param rows 一次请求返回多少数据
* @param callBack 回调函数
*/
@Override
public void getListData(int page, int rows, final CallBack callBack) {
String key = "9d3ce9c83fcd4c418dce2937c29b6414";
String param = "key=" + key + "&keyword=天才&page=" + page + "&rows=" + rows;
String url = "http://api.avatardata.cn/MingRenMingYan/LookUp?" + param;
OkHttpUtils.get()
.url(url)
.build()
.execute(new StringCallback() {
@Override
public void onResponse(String response, int id) {
GsonUtils utils =GsonUtils.getInstance();
AphorismsEntity aphorismsEntity = utils.fromJson(response, AphorismsEntity.class);
if ("Succes".equals(aphorismsEntity.getReason())) {
callBack.onSuccess(aphorismsEntity.getResult());
} else {
callBack.onError(response);
}
}
@Override
public void onError(Call call, Exception e, int id) {
callBack.onError(e.getMessage());
}
});
}
}
/**
* Controller控制器层(负责逻辑业务的处理).
*
* @author luyh
* @version 1.0
* @date 2019/04/08
*/
public class MainActivity extends AppCompatActivity implements CallBack {
private SmartRefreshLayout mSmartRefreshLayout;
private RecyclerView rcyAphorisms;
private LoadingDialog loadingDialog;
private AphorismsAdapter aphorismsAdapter;
private List<AphorismsEntity.ResultBean> resultBeanList = new ArrayList<>();
private int page = 1;
private IAphorismsAModel iAphorismsAModel;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
// XML相当于View层(负责界面数据的展示, 与用户进行交互)
setContentView(R.layout.activity_main);
mSmartRefreshLayout = findViewById(R.id.refresh_layout);
rcyAphorisms = findViewById(R.id.rcy_aphorisms);
LinearLayoutManager layoutManager = new LinearLayoutManager(this);
layoutManager.setOrientation(LinearLayoutManager.VERTICAL);
rcyAphorisms.setLayoutManager(layoutManager);
rcyAphorisms.setHasFixedSize(true);
rcyAphorisms.addItemDecoration(new DividerItemDecoration(this, DividerItemDecoration.VERTICAL));
rcyAphorisms.setItemAnimator(new DefaultItemAnimator());
aphorismsAdapter = new AphorismsAdapter(this);
rcyAphorisms.setAdapter(aphorismsAdapter);
// item的点击事件
aphorismsAdapter.setOnItemClickListener(new AphorismsAdapter.OnItemClickListener() {
@Override
public void onItemClick(View view, int position) {
String name = aphorismsAdapter.getData().get(position).getFamous_name();
Toast.makeText(MainActivity.this, "mvc: " + name, Toast.LENGTH_SHORT).show();
}
});
// 获取电影列表数据
iAphorismsAModel = new AphorismsAModelImpl();
loadingDialog = new LoadingDialog(this);
loadingDialog.setLoadingText("加载中...");
loadingDialog.show();
iAphorismsAModel.getListData(1, 10, this);
// 刷新数据
mSmartRefreshLayout.setOnMultiPurposeListener(new SimpleMultiPurposeListener() {
@Override
public void onRefresh(@NonNull RefreshLayout refreshLayout) {
super.onRefresh(refreshLayout);
runOnUiThread(new Runnable() {
@Override
public void run() {
page = 1;
iAphorismsAModel.getListData(1, 10, MainActivity.this);
mSmartRefreshLayout.finishRefresh();
}
});
}
@Override
public void onLoadMore(@NonNull RefreshLayout refreshLayout) {
super.onLoadMore(refreshLayout);
runOnUiThread(new Runnable() {
@Override
public void run() {
iAphorismsAModel.getListData(++page, 10, MainActivity.this);
}
});
}
});
}
@Override
public void onSuccess(Object response) {
if (loadingDialog != null) {
loadingDialog.close();
}
List<AphorismsEntity.ResultBean> list = (List<AphorismsEntity.ResultBean>) response;
if (list != null && list.size() > 0) {
resultBeanList.addAll(list);
aphorismsAdapter.addData(resultBeanList);
mSmartRefreshLayout.finishLoadMore();
} else {
Toast.makeText(this, "mvc: 数据已加载完毕", Toast.LENGTH_SHORT).show();
// 将不会再次触发加载更多事件
mSmartRefreshLayout.finishLoadMoreWithNoMoreData();
mSmartRefreshLayout.resetNoMoreData();
}
}
@Override
public void onError(String error) {
if (loadingDialog != null) {
loadingDialog.close();
}
Toast.makeText(this, "mvc: " + error, Toast.LENGTH_SHORT).show();
}
}
案例②

/**
* 泛型类的回调接口
*
* @param <T>
*/
public interface CallBack<T> {
void onSuccess(T response);
void onError(String error);
}
/**
* 数据模型层(负责处理数据的加载或者存储).
*
* @author luyh
* @version 1.0
* @date 2019/04/08
*/
public class AphorismsAModel {
/**
* 请求网络获取数据列表
*
* @param page 页码
* @param rows 一次请求返回多少数据
* @param callBack 回调函数
*/
public void getListData(int page, int rows, final CallBack callBack) {
String key = "9d3ce9c83fcd4c418dce2937c29b6414";
String param = "key=" + key + "&keyword=天才&page=" + page + "&rows=" + rows;
String url = "http://api.avatardata.cn/MingRenMingYan/LookUp?" + param;
OkHttpUtils.get()
.url(url)
.build()
.execute(new StringCallback() {
@Override
public void onResponse(String response, int id) {
GsonUtils utils = GsonUtils.getInstance();
AphorismsEntity aphorismsEntity = utils.fromJson(response, AphorismsEntity.class);
if ("Succes".equals(aphorismsEntity.getReason())) {
callBack.onSuccess(aphorismsEntity.getResult());
} else {
callBack.onError(response);
}
}
@Override
public void onError(Call call, Exception e, int id) {
callBack.onError(e.getMessage());
}
});
}
}
/**
* Controller控制器层(负责逻辑业务的处理).
*
* @author luyh
* @version 1.0
* @date 2019/04/08
*/
public class AphorismsController {
private AphorismsAModel aphorismsAModel;
public AphorismsController() {
aphorismsAModel = new AphorismsAModel();
}
/**
* 请求网络获取数据列表
*
* @param page 页码
* @param rows 一次请求返回多少数据
* @param callBack 回调函数
*/
public void getListData(int page, int rows, final CallBack callBack) {
aphorismsAModel.getListData(page, rows, callBack);
}
}
/**
* View层(负责界面数据的展示, 与用户进行交互).
*
* @author luyh
* @version 1.0
* @date 2019/04/08
*/
public class MainActivity extends AppCompatActivity implements CallBack {
private SmartRefreshLayout mSmartRefreshLayout;
private RecyclerView rcyAphorisms;
private LoadingDialog loadingDialog;
private AphorismsAdapter aphorismsAdapter;
private List<AphorismsEntity.ResultBean> resultBeanList = new ArrayList<>();
private int page = 1;
private AphorismsController aphorismsController;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
mSmartRefreshLayout = findViewById(R.id.refresh_layout);
rcyAphorisms = findViewById(R.id.rcy_aphorisms);
LinearLayoutManager layoutManager = new LinearLayoutManager(this);
layoutManager.setOrientation(LinearLayoutManager.VERTICAL);
rcyAphorisms.setLayoutManager(layoutManager);
rcyAphorisms.setHasFixedSize(true);
rcyAphorisms.addItemDecoration(new DividerItemDecoration(this, DividerItemDecoration.VERTICAL));
rcyAphorisms.setItemAnimator(new DefaultItemAnimator());
aphorismsAdapter = new AphorismsAdapter(this);
rcyAphorisms.setAdapter(aphorismsAdapter);
// item的点击事件
aphorismsAdapter.setOnItemClickListener(new AphorismsAdapter.OnItemClickListener() {
@Override
public void onItemClick(View view, int position) {
String name = aphorismsAdapter.getData().get(position).getFamous_name();
Toast.makeText(MainActivity.this, "mvc: " + name, Toast.LENGTH_SHORT).show();
}
});
// 获取电影列表数据
aphorismsController = new AphorismsController();
loadingDialog = new LoadingDialog(this);
loadingDialog.setLoadingText("加载中...");
loadingDialog.show();
aphorismsController.getListData(1, 10, this);
// 刷新数据
mSmartRefreshLayout.setOnMultiPurposeListener(new SimpleMultiPurposeListener() {
@Override
public void onRefresh(@NonNull RefreshLayout refreshLayout) {
super.onRefresh(refreshLayout);
runOnUiThread(new Runnable() {
@Override
public void run() {
page = 1;
aphorismsController.getListData(1, 10, MainActivity.this);
mSmartRefreshLayout.finishRefresh();
}
});
}
@Override
public void onLoadMore(@NonNull RefreshLayout refreshLayout) {
super.onLoadMore(refreshLayout);
runOnUiThread(new Runnable() {
@Override
public void run() {
aphorismsController.getListData(++page, 10, MainActivity.this);
}
});
}
});
}
@Override
public void onSuccess(Object response) {
if (loadingDialog != null) {
loadingDialog.close();
}
List<AphorismsEntity.ResultBean> list = (List<AphorismsEntity.ResultBean>) response;
if (list != null && list.size() > 0) {
resultBeanList.addAll(list);
aphorismsAdapter.addData(resultBeanList);
mSmartRefreshLayout.finishLoadMore();
} else {
Toast.makeText(this, "mvc: 数据已加载完毕", Toast.LENGTH_SHORT).show();
// 将不会再次触发加载更多事件
mSmartRefreshLayout.finishLoadMoreWithNoMoreData();
mSmartRefreshLayout.resetNoMoreData();
}
}
@Override
public void onError(String error) {
if (loadingDialog != null) {
loadingDialog.close();
}
Toast.makeText(this, "mvc: " + error, Toast.LENGTH_SHORT).show();
}
}
以下是两个案例中的源代码:
① 链接:https://pan.baidu.com/s/1jmhjnbOdYxi0qaSl1HzxHg 提取码:cwfy
② 链接:https://pan.baidu.com/s/1eGme7KjbIgpG4C75sfHvKA 提取码:3m3e
两个案例的区别:
①中,使用的是Activity直接作为Controller控制器来使用;
②中,将Controller控制器直接抽离出来一个类,而Activity仅仅属于视图层。

本文总结了Android的MVC开发模式,详细解释了Model、View和Controller的职责,探讨了其优缺点,如降低耦合、提高重用性以及视图和控制器间的紧密联系可能带来的问题。此外,还提供了实际案例以加深理解。

640

被折叠的 条评论
为什么被折叠?



