MVP架构搭建
来源:互联网 发布:c语言中随机数怎么写 编辑:程序博客网 时间:2024/06/02 06:14
1. 关于MVC
MVC 全称是Model - View - Controller,是模型(model)-视图(view)-控制器(controller)的缩写。
Model:业务逻辑和数据处理(数据库存储操作,网络数据请求,复杂算法,耗时操作),专为存储和管理应用数据而生。
View:XML布局(凡是能够在屏幕上看见的对象,都是视图对象);
Controller:用户交互(读取View视图,向Moder发送数据请求,让数据显示在界面上),包括响应View对象触发的各类事件和管理着模型对象和视图层间的数据流动。
以点击按钮为例:用户输入-用户与视图对象进行交互-视图发送消息到控制器-控制器更新模型对象数据-控制器从他的视图感兴趣的模型对象中获取数据-控制器根据模型对象的变化更新视图。
优点:Model层和View层不直接交互,把UI界面和业务逻辑、数据处理分离。
缺点:Activity控制器中有很多显示UI的代码,因此View视图和控制器Controller不是完全分离的,也就是说View视图和控制器Controller绑定在一个类中,当布局复杂的时候,Activity会非常冗余繁杂,解耦不完美。
2. 关于MVP
MVP 全称是Model - View - Presenter ,是模型(model)-视图(view)-呈现器(presenter)的缩写。
Moder:业务逻辑和数据处理(数据库存储操作,网络数据请求,复杂算法,耗时操作);
View:负责界面数据的展示,与用户进行交互(Activity);
Presenter:作为Moder和View的桥梁。
逻辑:将Activity(也就是将View和Controller合并为View)作为View,Model不变,并添加Presenter;View和Model不直接交互,而是使用Presenter作为桥梁。Presenter同时拥有View和Model的Interface引用,而View层有Presenter的Interface引用。当View层需要展示数据的时候,会调用Presenter层的接口,然后Presenter会调用Model请求数据,当Model层数据加载成功后会调用Presenter的回调方法通知Presenter层数据加载完毕,最后Presenter层会调用View层的接口将加载的数据展示给用户。
优点:将View和Moder完全分离,互不依赖。
3. MVC 与 MVP的区别
- MVC中的Moder、View和Controller两两之间都有联系。
- MVP中的Moder与View不能直接联系,只能通过Presenter发生关系。
4. 登录经典示例说明MVP架构以及架构之间接口的连接方式
4.1 业务需求:
- 输入帐号和密码,点击Login实现登录,点击Clear实现清空帐号和密码。
4.2 Model:
- 创建User模型实体类:
public class User { private String username; private String password; public String getUsername() { return username; } public void setUsername(String username) { this.username = username; } public String getPassword() { return password; } public void setPassword(String password) { this.password = password; }}
- 创建Model业务逻辑接口类IUserBiz:
public interface IUserBiz { public void login(String name, String password, OnLoginListener loginListener);}
- 定义Model成功失败回调类接口OnLoginListener:
public interface OnLoginListener { void loginSuccess(User user); void loginFailed();}
- 定义Model业务逻辑实现类UserBiz:
public class UserBiz implements IUserBiz { @Override public void login(final String name, final String password, final OnLoginListener loginListener) { //模拟子线程耗时操作 new Thread() { @Override public void run() { try { Thread.sleep(2000); } catch (InterruptedException e) { e.printStackTrace(); } //模拟登录成功 if ("fkq".equals(name) && "123".equals(password)) { User user = new User(); user.setUsername(name); user.setPassword(password); loginListener.loginSuccess(user); } else { loginListener.loginFailed(); } } }.start(); }}
说明:
- 定义一个业务逻辑接口,一个实现类,实现类里面请求数据。
- 定义一个数据请求回调接口,请求到了数据回调接口中的成功方法,没有请求到数据回调接口中的失败方法。
4.3 Presenter:
- 创建Presenter接口UserLoginPresenter:
public class UserLoginPresenter { private IUserBiz userBiz; private ILoginView userLoginView; private Handler mHandler = new Handler(); public UserLoginPresenter(ILoginView userLoginView) { this.userBiz = new UserBiz(); this.userLoginView = userLoginView; } public void login() { userLoginView.showLoading(); userBiz.login(userLoginView.getUserName(), userLoginView.getPassword(), new OnLoginListener() { @Override public void loginSuccess(final User user) { //需要在UI线程执行 mHandler.post(new Runnable() { @Override public void run() { userLoginView.toMainActivity(user); userLoginView.hideLoading(); } }); } @Override public void loginFailed() { //需要在UI线程执行 mHandler.post(new Runnable() { @Override public void run() { userLoginView.showFailedError(); userLoginView.hideLoading(); } }); } }); } public void clear() { userLoginView.clearUserName(); userLoginView.clearPassword(); }}
说明:创建UserLoginPresenter接口,接口中拿着Model和View的接口,并具体实现Model成功回调和失败回调后的方法,也就是说Model请求数据成功过后应该怎么具体做,请求数据失败后应该怎么做。
4.4 View
- 创建View的接口类ILoginView:
public interface ILoginView { String getUserName(); String getPassword(); void clearUserName(); void clearPassword(); void showLoading(); void hideLoading(); void toMainActivity(User user); void showFailedError();}说明:对于View接口主要考虑功能上的操作:1. 该操作需要什么?(getUserName, getPassword)2. 该操作的结果,对应的反馈?(toMainActivity, showFailedError)3. 该操作过程中对应的友好的交互?(showLoading, hideLoading)
- 创建activity_user_login.xml布局文件:
<?xml version="1.0" encoding="utf-8"?><RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent" android:layout_height="match_parent"> <LinearLayout android:id="@+id/ll_username" android:layout_width="match_parent" android:layout_height="wrap_content" android:gravity="center"> <TextView android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="UserName:" /> <EditText android:id="@+id/et_username" android:layout_width="wrap_content" android:layout_height="wrap_content" android:hint="请输入用户名" /> </LinearLayout> <LinearLayout android:id="@+id/ll_password" android:layout_width="match_parent" android:layout_height="wrap_content" android:layout_below="@id/ll_username" android:gravity="center"> <TextView android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="Password:" /> <EditText android:id="@+id/et_password" android:layout_width="wrap_content" android:layout_height="wrap_content" android:hint="请输入密码" /> </LinearLayout> <LinearLayout android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_below="@id/ll_password" android:layout_centerHorizontal="true" android:layout_marginTop="50sp"> <Button android:id="@+id/bt_login" android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="Login" /> <Button android:id="@+id/bt_clear" android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="Clear" /> </LinearLayout> <ProgressBar android:id="@+id/pb_progressbar" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_centerInParent="true" android:visibility="gone" /></RelativeLayout>
- 创建View接口实现类UserLoginActivity:
public class UserLoginActivity extends AppCompatActivity implements ILoginView { @BindView(R.id.et_username) EditText etUsername; @BindView(R.id.et_password) EditText etPassword; @BindView(R.id.pb_progressbar) ProgressBar pbProgressbar; @BindView(R.id.bt_login) Button btLogin; @BindView(R.id.bt_clear) Button btClear; private UserLoginPresenter userLoginPresenter = new UserLoginPresenter(this); @Override protected void onCreate(@Nullable Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_user_login); ButterKnife.bind(this); } @Override public String getUserName() { return etUsername.getText().toString().trim(); } @Override public String getPassword() { return etPassword.getText().toString().trim(); } @Override public void clearUserName() { etUsername.setText(""); } @Override public void clearPassword() { etPassword.setText(""); } @Override public void showLoading() { pbProgressbar.setVisibility(View.VISIBLE); } @Override public void hideLoading() { pbProgressbar.setVisibility(View.GONE); } @Override public void toMainActivity(User user) { startActivity(new Intent(this, MainActivity.class)); Toast.makeText(this,"登陆成功",Toast.LENGTH_SHORT).show(); } @Override public void showFailedError() { Toast.makeText(this,"登陆失败",Toast.LENGTH_SHORT).show(); } @OnClick(R.id.bt_login) public void onBtLoginClicked() { userLoginPresenter.login(); } @OnClick(R.id.bt_clear) public void onBtClearClicked() { userLoginPresenter.clear(); }}说明:负责界面的展示以及处理与用户的交互。
5. 为什么说MVP是优秀的架构模式?
低耦合:MVP拆分了MVC臃肿的Activity,独立了Model、View、Presenter,并通过接口的方式进行链接,板块化实现了低耦合。
高复用:Presenter、Model与Activity(View)的关系实现了一对多。
易测试:独立了Model、View、Presenter以后,更加方便进行单元测试。
好维护:低耦合就成就了好维护。
- MVP架构搭建
- Android MVP架构搭建
- MVP架构快速搭建Dagger
- android dagger2搭建mvp架构
- 5分钟搭建MVP架构
- mvp+okgo+butterknife搭建android app架构
- Android APP架构的那点事儿[MVP架构搭建]
- MVP架构
- MVP架构
- MVP架构
- MVP架构
- MVP架构
- 架构mvp
- MVP-架构
- MVP架构实现的Github客户端(2-搭建项目框架)
- Android MVP架构项目搭建封装,基类封装
- 基于Android真实项目教你一步一步搭建架构2 -- Google官方Mvp架构
- 【Android编程架构】mvp架构
- Inventor API:用C++导出3D PDF
- Linux上传下载文件/文件夹
- 解析xml的四种方式:DOM JDOM DOM4J SAX
- 用于实时大数据处理的Lambda架构
- 利用SharePreferences保存实体对象
- MVP架构搭建
- Link-Cut Tree
- Java传值还是传引用问题
- 【Unity】unity3d 数据加/解密
- Java反射实例分析
- 版本控制工具SVN的使用方法
- iOS 支持https
- 管理数据的价值
- Inverse是hibernate双向关系中的基本概念