- 模式说明
示意图
- 优点:(对比MVC模式)
- 耦合度更低:通过
Presenter
实现数据和视图之间的交互,完全隔离了View层与Mode层,二者互不干涉
避免了
View
、Model
的直接联系,又通过Presenter
实现两者之间的沟通
Activity
代码变得更加简洁:简化了Activity
的职责,仅负责UI相关操作,其余复杂的逻辑代码提取到了Presenter
层中进行处理
2.3 MVVM
为了更加分离M、V层,更加释放Activity的压力,于是出现了MVVM模式
- 定义
VM
层:ViewModel
,即 View的数据模型和Presenter的合体
基本上与
MVP
模式完全一致,将逻辑处理层Presenter
改名为ViewModel
- 模式说明
示意图
- 优点
使得视图层(View)
& 控制层(Controller)
之间的耦合程度进一步降低,关注点分离更为彻底,同时减轻了Activity
的压力
本文主要讲解MVC和MVP模式,不过多阐述MVVM模式.
3. MVC、MVP模式的区别
================
示意图
4. 三种模式出现的初衷
=============
MVC
模式的出现
为解决程序模块化问题,于是MVC模式出现了:将业务逻辑、数据处理与界面显示进行分离来组织代码,即分成M、V、C层;
MVP
模式的出现
但M、V层还是有相互交叉、隔离度不够,同时写到Activity上使得Activity代码臃肿,于是出现了MVP: 隔离了MVC中的 M 与 V 的直接联系,将M、V层更加隔离开来,并释放了Activity的压力;
MVVM
模式的出现
为了更加分离M、V层,更加释放Activity的压力,于是出现了MVVM: 使得V和M层之间的耦合程度进一步降低,分离更为彻底,同时更加减轻了Activity的压力。
下面,我将详细讲解一下最常用的MVP
模式的核心思想 & 使用
5. MVP模式详解
===========
此处主要详细分析MVP模式的核心思想,并实例说明。
5.1 核心思想
把Activity里的逻辑都抽离到View
和Presenter
接口中去 & 由具体的实现类来完成。具体实现思路如下:
-
把
Activity
中的UI
逻辑抽象成View
接口 & 由具体的实现类来完成 -
把业务逻辑抽象成
Presenter
接口 & 由具体的实现类来完成 -
Model
类还是原来MVC
模式的Model
层
5.2 实现步骤
MVP
模式的UML
图
示意图
通过UML
图可看出,使用MVP
模式的步骤如下:
示意图
5.3 实例讲解
本节通过一个 英语词典app
实例 讲解 MVP
模式具体的实现
前言:工程项目的列表架构
MVP
技术架构的项目结构非常清晰:把M
、V
、P
层分别分为三个文件夹:Model
、View
、Presenter
,每个文件下分别是对应的接口和实现的类
其中
Model
层的fanyi
类是作为实现用GSON
解析JSON
信息的一个JavaBean
步骤1:设置View层(IView接口 & 实现类)
/**
-
View接口:IfanyiView
-
需定义在实现类中需要用到的方法
*/
public interface IfanyiView {
void init();//初始化
void SetInfo(String str); //输出翻译信息
void SetError(); //输出出错信息
}
/**
-
View实现类:MainActivity类
-
注:由于MainActivity是对应View层的实现类,所以要实现View层的接口
*/
public class MainActivity extends AppCompatActivity implements IfanyiView {
private EditText et;
private TextView tv;
CidianPresenter cidianPresenter; // 声明了Presenter对应类
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
// 实例化P对应类的对象和findView
init();
// 接受用户的输入
findViewById(R.id.btnfanyi).setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
//将View层获得的数据传入Presenter层 ,注意还要传递MainActivity
cidianPresenter.InputToModel(et.getText().toString(), MainActivity.this);
}
});
}
@Override
public void init(){
//实例化P类的对象和findView
cidianPresenter = new CidianPresenter(this);
et = (EditText) findViewById(R.id.editText);
tv = (TextView) findViewById(R.id.tv);
}
@Override
//输出出错信息
public void SetError() {
tv.setText(“查询不成功,请检查网络”);
}
//输出翻译信息
@Override
public void SetInfo(String str){
tv.setText(str);
}
}
// 从上述代码可看出,MainActivity只做了FindView、setListener的工作(包含了cidianPresenter),简洁清爽!
步骤2:设置Presenter层(创建IPresenter接口&实现类)
/**
-
Presenter接口:ICidianPresenter
-
需定义在实现类中需要用到的方法
*/
public interface ICidianPresenter {
void InputToModel(String input,Context context); // 将View层获得的数据传入Model层
}
/**
-
Presenter层的实现类:CidianPresenter类
-
注:由于CidianPresenter是对应Presenter层的实现类,所以要实现Presenter层的接口
*/
public class CidianPresenter implements onfanyiListener,ICidianPresenter {
// 1. 声明View层对应接口、Model层对应的类
IfanyiView fyV;
fanyimodel fanyimodel;
// 2. 重构函数,初始化View接口实例、Model实例
public CidianPresenter(IfanyiView fyV){
this.fyV = fyV;
fanyimodel = new fanyimodel();
}
// 3.将View层获得的数据传入Model层,注意要传递this.当前类
@Override
public void InputToModel(String input, Context context){
fanyimodel.HandleData(input, context, this);
}
// 回调函数,调用UI更新
@Override
public void onSuccess(String str) {
fyV.SetInfo(str); }
// 回调函数,调用UI输出出错信息
@Override
public void onError() {
fyV.SetError(); }
}
// 注:
// a. 保留IfanyiView的引用,就可直接在CidianPresenter当前类进行UI操作而不用在Activity操作
// b. 保留了Model层的引用就可以将View层的数据传递到Model层
步骤3:Model层(Model层接口 & 实现类)
/**
-
Model层接口:Ifanyi
-
需定义在实现类中需要用到的方法
*/
public interface Ifanyi {
void HandleData(String input,Context context,final onfanyiListener listener);
String fanyiToString(fanyi fy);
}
/**
-
Model层的实现类:fanyiModel类
-
注:由于fanyiModel是对应Model层的实现类,所以要实现Model层的接口
*/
public class fanyimodel implements Ifanyi {
private fanyi fy = new fanyi();
public void HandleData(String input,Context context,final onfanyiListener listener){
// 使用Volley框架来实现异步从网络的有道API获取翻译数据
RequestQueue mQueue = Volley.newRequestQueue(context);
StringRequest stringRequest = new StringRequest(“http://fanyi.youdao.com/openapi.do?keyfrom=Yanzhikai&key=2032414398&type=data&doctype=json&version=1.1&q=”+input, new Response.Listener() {
@Override
public void onResponse(String s) {
// 用Gson方式解析获得的json字符串
Gson gson = new Gson();
fy = gson.fromJson(s.trim(),fy.getClass());
// 回调监听器的函数把处理数据后的结果(翻译结果)返回给Presenter层
listener.onSuccess(fanyiToString(fy));
}
}, new Response.ErrorListener() {
最后
我坚信,坚持学习,每天进步一点,滴水穿石,我们离成功都很近!
以下是总结出来的字节经典面试题目,包含:计算机网络,Kotlin,数据结构与算法,Framework源码,微信小程序,NDK音视频开发,计算机网络等。
字节高级Android经典面试题和答案
《Android学习笔记总结+移动架构视频+大厂面试真题+项目实战源码》,点击传送门,即可获取!
= gson.fromJson(s.trim(),fy.getClass());
// 回调监听器的函数把处理数据后的结果(翻译结果)返回给Presenter层
listener.onSuccess(fanyiToString(fy));
}
}, new Response.ErrorListener() {
最后
我坚信,坚持学习,每天进步一点,滴水穿石,我们离成功都很近!
以下是总结出来的字节经典面试题目,包含:计算机网络,Kotlin,数据结构与算法,Framework源码,微信小程序,NDK音视频开发,计算机网络等。
字节高级Android经典面试题和答案
[外链图片转存中…(img-oxCMuRA6-1715414717878)]
[外链图片转存中…(img-EHg4Mfzc-1715414717878)]
《Android学习笔记总结+移动架构视频+大厂面试真题+项目实战源码》,点击传送门,即可获取!