关于mvp
来源:互联网 发布:运营商的云计算项目 编辑:程序博客网 时间:2024/06/06 22:00
说到mvp 不得不说的就是mvc 了 来先看一个经典的图
C和P的区别
1、先看C
C 就是 Controller,控制器。负责从 View 读取数据,控制用户输入,并向 Model 发送数据。简单来说,就是起到一个沟通的作用,能很大程度上的解决 Model 和 View 的耦合问题。
换句话说就是,它是一个 Model 与 View 之间的桥梁,让 Model 和 View 之间不再紧紧关联。
比如 View 接收到了用户输入数据,先交给 Controller ,Controller 再转交给 Model ,反之亦然。
但是如果controller 有问题 view 跟model 也能直接沟通
2、观察一下P
p即 Presenter 主持人。。。好 我们叫主持吧。。 作用跟跟 C 类似,仍然是负责 View 和 Model 之间的沟通。但是它彻底让 View 和 Model 不能直接沟通。如果想要沟通,就必须通过这个主持者来主持它们两个应该干啥。
比如 View 接收到了用户输入数据,不能直接给 Model ,要交给 Presenter ,Presenter 再转交给 Model ,反之亦然。
如果view接收到了用户操作必须要先交给Presenter再通过Presenter去转交给model 反过来也是 当model 改变了 也必须通过Presenter来反过来通知view去更新 不能像mvc一样model 改变view直接就能刷新了
3、简单的区别
C 和 P 都是为了解放 Model 和 View 之间的联系,只不过 C 是很大程度上解决,但 P 是彻底让它们两断了联系。
也就是c让model 、View 松散耦合,p让Model、View 解耦
来看下详细的区别
1、mvc
从下图中我们可以看到
*用户 Event(事件)会导致 Controller 改变 Model 或 View 或同时改变两者。
*只要 Controller 改变了 Model 的数据或属性,所有依赖的 View 都会自动更新。
*类似的,只要 Controller 改变了 View ,View 会从潜在的 Model 中获取数据进行更新。
2、mvp
Presenter 中同时持有 View 以及 Model 的 Interface 引用,而 View 持有 Presenter 的实例。
当某个 View 需要展示某些数据时,首先会调用 Presenter 的某个接口,然后 Presenter 会调用 Model 请求数据。
当 Model 数据加载成功后会调用 Presenter 的回调方法通知 Presenter 数据加载完毕,最后 Presenter 再调用 View 层接口展示加载后数据。
3、主要区别
在 MVC 中:
View 可以与 Model 直接交互;
Controller 可以被多个 View 共享;
Controller 可以决定显示哪个 View。
在 MVP 中:
View 不直接与 Model 交互;
Presenter 与 View 通过接口来交互,更有利于添加单元测试;
通常 View 与 Presenter 是一对一的,但复杂的 View 可能绑定多个 Presenter 来处理;
Presenter 也可以直接进行 View 上的渲染。
好先看下经典的目录结构吧
好像是看不出什么来 这就是一个简单的登陆demo 万年不变
我们可以来分析一下
通过上面的介绍我们可以知道,Presenter 是用来Model 和View 之间交互的 所以必须要持有他们各自的对象
model 还要有一个业务类 这在mvc中也是一样的 索性我们就抽一个接口出来
Presenter 与view 又是通过接口来交互的所以我们就需要给view 定义一个接口
所以我们就要看到底需要什么东西
Model:负责检索操作数据,也就是常见的业务类对bean的操作
ModelInterface: 处理bean的业务逻辑接口 由bean来实现
view:暂时就看出activity 用来记录响应用户操作的
viewInterface : view 要实现用户操作的结果接口(比如登陆 界面上肯定有登陆注册按键 就要有 登陆成功失败的接口以及注册成功失败的接口)Presenter 通过 它 与view交互
Presenter 是个类 是用来连接view 与model的桥梁 持有二者的接口对象
好吧 看起来非常多 但是逻辑确实是清晰了一点 谁是干什么的 谁控制谁响应 这种是清晰了一点。。我体会还不深 勿喷
ok 现在我们可以抽取代码了
1、bean
/** * Created by MnyZhao on 2017/11/3. */public class UserBean { /*名字*/ private String name; /*密码*/ private String passWord; public String getName() { return name; } public void setName(String name) { this.name = name; } public String getPassWord() { return passWord; } public void setPassWord(String passWord) { this.passWord = passWord; }}
2、业务操作接口 业务操作类 针对bean
UserModelInterface
/** * Created by MnyZhao on 2017/11/3. * @description 业务操作接口 控制user的动作接口 * @remark */public interface IUserModel { /*注册接口*/ boolean onRegister(String name,String passWord); /*登陆接口*/ boolean onLogin(String name,String passWord);}
实现类 UserModel
/** * Created by MnyZhao on 2017/11/3. * model类 实现IUserModel中的动作接口 */public class UserModel implements IUserModel { private Map<String, String> userMap = new HashMap<>(); /** * 注册账号放入集合 * * @param name 用户名 * @param passWord 密码 * @return 返回是否成功(true or false) */ @Override public boolean onRegister(String name, String passWord) { if (!userMap.containsKey(name)) { userMap.put(name, passWord); return true; } return false; } /** * 登陆接口 * * @param name 用户名 * @param passWord 密码 * @return 是否登陆成功(true or false) */ @Override public boolean onLogin(String name, String passWord) { return passWord.equals(userMap.get(name)); }}
3、现在我们要看看view了
ViewInterface 针对界面用户操作的相应接口
/** * Created by MnyZhao on 2017/11/3. */public interface IUserVIew { //检查输入的合法性 boolean checkInputInfo(); //注册成功 void onRegisterSucceed(); //注册失败 void onRegisterFaild(); //登录成功 void onLoginSucceed(); //登录失败 void onLoginFaild();}
4、model view 都有了 我们就要Presenter了
Presenter类 用来沟通view 与model
所以要持有二者的接口对象
/** * Created by MnyZhao on 2017/11/3. */public class UserPresenter { private IUserModel mUserModel; private IUserVIew mIuserView; public UserPresenter(IUserVIew mIuserView) { this.mUserModel = new UserModel(); this.mIuserView = mIuserView; } public void registerUser(String name, String pwd) { //根据Model中的结果调用不同的方法进行UI展示 if (mUserModel.onRegister(name, pwd)) { mIuserView.onRegisterSucceed(); } else { mIuserView.onRegisterFaild(); } } public void loginUser(String name, String pwd) { //根据Model中的结果调用不同的方法进行UI展示 if (mUserModel.onLogin(name, pwd)) { mIuserView.onLoginSucceed(); } else { mIuserView.onLoginFaild(); }
5、接下来就要在activity(view)中实现了 需要实现view的接口(IUserVIew)并持有 Presenter的实例才能与view 进行交互
public class MainActivity extends AppCompatActivity implements IUserVIew { private TextInputLayout mTilName; private TextInputLayout mTilPassword; private TextInputEditText mTieName; private TextInputEditText mTiePassWord; private Button mBtnRegister, mBtnLogin; private UserPresenter userPeresenter; private String name, pwd; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); initView(); initUserPersenter(); } private void initView() { mTilName = (TextInputLayout) findViewById(R.id.til_name); mTilPassword = (TextInputLayout) findViewById(R.id.til_password); mTieName = (TextInputEditText) findViewById(R.id.tie_name); mTiePassWord = (TextInputEditText) findViewById(R.id.tie_password); mBtnRegister = (Button) findViewById(R.id.btn_register); mBtnLogin = (Button) findViewById(R.id.btn_login); mBtnRegister.setOnClickListener(viewListener); mBtnLogin.setOnClickListener(viewListener); } private View.OnClickListener viewListener = new View.OnClickListener() { @Override public void onClick(View v) { switch (v.getId()) { case R.id.btn_login: if (checkInputInfo()) { userPeresenter.loginUser(name, pwd); } break; case R.id.btn_register: if (checkInputInfo()) { userPeresenter.registerUser(name, pwd); } break; } } }; private void initUserPersenter() { this.userPeresenter = new UserPresenter(this); } @Override public boolean checkInputInfo() { name = mTieName.getText().toString().trim(); pwd = mTiePassWord.getText().toString().trim(); if (("").equals(name)) { mTilName.setError("Name is not null"); return false; } if (("").equals(pwd)) { mTilPassword.setError("PassWord is not null"); return false; } return true; } @Override public void onRegisterSucceed() { Toast.makeText(this, "Register Successful", Toast.LENGTH_SHORT).show(); } @Override public void onRegisterFaild() { Toast.makeText(this, "Register Error", Toast.LENGTH_SHORT).show(); } @Override public void onLoginSucceed() { Toast.makeText(this, "Login Successful", Toast.LENGTH_SHORT).show(); } @Override public void onLoginFaild() { Toast.makeText(this, "Login Error", Toast.LENGTH_SHORT).show(); }}
到此 代码详细无比 只要复制粘贴就能完美运行。。哦还少一些资源文件。。等我补上
drawable
<?xml version="1.0" encoding="UTF-8"?><shape xmlns:android="http://schemas.android.com/apk/res/android" android:shape="rectangle"> <!-- 填充的颜色 --> <solid android:color="#63B8FF" /> <!-- 设置按钮的四个角为弧形 --> <!-- android:radius 弧形的半径 --> <corners android:radius="10px" /> <!-- padding:Button里面的文字与Button边界的间隔 --> <padding android:left="20px" android:top="20px" android:right="20px" android:bottom="20px" /></shape><?xml version="1.0" encoding="UTF-8"?><shape xmlns:android="http://schemas.android.com/apk/res/android" android:shape="rectangle"> <!-- 填充的颜色 --> <solid android:color="#FFFFFF" /> <!-- 设置按钮的四个角为弧形 --> <!-- android:radius 弧形的半径 --> <corners android:radius="10px" /> <!-- padding:Button里面的文字与Button边界的间隔 --> <padding android:left="20px" android:top="20px" android:right="20px" android:bottom="20px" /></shape>
xml
<?xml version="1.0" encoding="utf-8"?><LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:app="http://schemas.android.com/apk/res-auto" xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent" android:layout_height="match_parent" android:orientation="vertical" android:padding="10dp" tools:context="com.mnyzhao.mymvpdemo.MainActivity"> <android.support.design.widget.TextInputLayout android:id="@+id/til_name" android:layout_width="match_parent" android:layout_height="wrap_content" android:textColorHint="@color/colorAccent" app:errorTextAppearance="@color/colorPrimaryDark"> <android.support.design.widget.TextInputEditText android:id="@+id/tie_name" android:layout_width="match_parent" android:layout_height="wrap_content" android:hint="User" android:textColor="@color/colorAccent" android:textColorHint="@color/colorAccent" /> </android.support.design.widget.TextInputLayout> <android.support.design.widget.TextInputLayout android:id="@+id/til_password" android:layout_width="match_parent" android:layout_height="wrap_content" android:layout_marginTop="20dp" android:textColorHint="@color/colorAccent"> <android.support.design.widget.TextInputEditText android:id="@+id/tie_password" android:layout_width="match_parent" android:layout_height="wrap_content" android:hint="PassWord" android:textColor="@color/colorAccent" /> </android.support.design.widget.TextInputLayout> <LinearLayout android:layout_width="match_parent" android:layout_height="wrap_content" android:layout_marginTop="20dp" android:gravity="center" android:orientation="horizontal" android:paddingLeft="20dp" android:paddingRight="20dp"> <Button android:id="@+id/btn_register" android:layout_width="match_parent" android:layout_height="60dp" android:layout_weight="1" android:background="@drawable/whiteshape" android:text="Register" android:textAllCaps="false" android:textColor="#63B8FF" android:textSize="18sp" /> <Button android:layout_width="30dp" android:layout_height="wrap_content" android:visibility="invisible" /> <Button android:id="@+id/btn_login" android:layout_width="match_parent" android:layout_height="60dp" android:layout_weight="1" android:background="@drawable/blueshape" android:text="Login" android:textAllCaps="false" android:textColor="@android:color/white" android:textSize="18sp" /> </LinearLayout></LinearLayout>
如果你还不能运行 那 可能你缺少Material Design的包
compile 'com.android.support:design:25.+'
ok 如果还不行的话 那对不起 可能我不适合写代码………….
还是放上资源链接吧 不知道为什么 没有0积分的选项。。。
Demo
- 关于MVP
- 关于mvp
- 关于mvp
- 关于 MVP 奖励计划
- 关于MVC、MVP架构
- 关于The MVP
- 关于Mvc,Mvp,PureMvc
- 一些关于MVP的资料
- 关于MVP的一些思考
- 关于Android MVP设计模式
- 关于MVP模式集成框架
- 关于MVP的一些理解
- 关于mvp模式自己的一些见解
- 关于mvp模式自己的一些见解
- 关于Android MVP模式的思考
- 关于Android 的MVP的理解
- 自己关于mvp的一点总结
- 关于MVP模式的使用设计
- python中scrapy的学习
- mysql-语句
- 时间复杂性求解
- 奇异值分解(SVD)原理详解及推导
- HDU 5936 Difference 折半枚举,暴力
- 关于mvp
- 世界名画陈列馆问题-重复&不重复两种
- 【2-SAT】【AtCoder Regular Contest 069 F】Flag
- Android中Json数据格式的解析
- Controller for AR.Drone
- An error occurred while collecting items to be installed session context was
- SEO网络优化是什么工作
- tensorflow的一些基本函数
- 日常学习——区间覆盖