菜鸟级教程:MVP是啥玩意儿

2023-12-09 21:30
文章标签 教程 mvp 菜鸟 玩意儿

本文主要是介绍菜鸟级教程:MVP是啥玩意儿,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

这几天一直加班,好不容易到了周末,就狂睡一通,结果白天睡觉,晚上反而睡不着了。闲着也么事,就起来写写博客吧,记录一下最近工作中遇到的问题。
<pre code_snippet_id="1900355" snippet_file_name="blog_20160926_1_7452424" name="code" class="java">刚进新公司的时候,接手了公司的项目,可是刚拿到代码就蒙了,完全看不懂。。。新公司用的是MVP架构,但是我之前的公司用的是MVC架构,有的人可能就会问了,为了么MVP架构这么流行,还有公司不去用它,这个我也没办法,也不是我们今天讨论的话题。
 

拿着公司的代码,边做功能边学习MVP,这个还是比较痛苦的,刚开始什么都看不懂,方法在哪里被调用的也看不出来,只能慢慢摸索,好在这两天的努力没白费,终于把MVP弄懂了,下面我就以我的思路来解释一下什么叫MVP。

我们就写一个简单的Demo吧,从实例中来学习比较快。网上大部分的MVP例子都是登录注册,我也来写一个登录注册。

首先,我们需要定义一个资源文件

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"xmlns:tools="http://schemas.android.com/tools"android:layout_width="match_parent"android:layout_height="match_parent"android:orientation="vertical"><EditTextandroid:id="@+id/username_et"android:hint="请输入账号"android:layout_width="match_parent"android:layout_height="wrap_content" /><EditTextandroid:id="@+id/password_et"android:hint="请输入密码"android:layout_width="match_parent"android:layout_height="wrap_content"android:inputType="textPassword" /><Buttonandroid:id="@+id/login_btn"android:layout_width="wrap_content"android:layout_height="wrap_content"android:text="登录"/></LinearLayout>

代码很简单,一个账号输入框,一个密码输入框,一个登录按钮


然后看一下,不使用MVP模式的MainActivity代码:

public class MainActivity extends Activity implements OnClickListener {private static final String TAG = "MainActivity";public static final String USERNAME="wuzhanglao";public static final String PASSWORD="470782682";private EditText username_et;private EditText password_et;private Button login_btn;@Overrideprotected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);setContentView(R.layout.activity_main);initView();}private void initView() {username_et = (EditText) findViewById(R.id.username_et);password_et = (EditText) findViewById(R.id.password_et);login_btn = (Button) findViewById(R.id.login_btn);login_btn.setOnClickListener(this);}@Overridepublic void onClick(View v) {switch (v.getId()) {case R.id.login_btn:String username = username_et.getText().toString();String password = password_et.getText().toString();if(username.isEmpty() || password.isEmpty()){Log.d(TAG, "账号或者密码不能为空");} else if(username.length() <8 || password.length()<9){Log.d(TAG, "账号至少8位,密码至少10位");} else if(username.equals(USERNAME)){if(password.endsWith(PASSWORD)){Log.d(TAG, "恭喜你,登录成功");} else {Log.d(TAG, "登录失败->密码错误");}}break;}}
}

前面的都不用看,直接看onClick()方法里面,大家有没有看到,case R.id.login_btn后面的代码有点多,有的人就问啦,不是很多啦,也就十几行。对,也就十几行,但是正式的公司项目中是不可能只有一个点击事件的,也就是switch语句里面会有很多case语句,到时候修改代码的时候可以把你烦死,一个switch块就有几百行几千行代码,会疯掉的~~~ 发火反正我看到这种代码就没好心情了


下面我们稍微改进一下,让代码简洁一些,请看我是如何修改的:

@Override
public void onClick(View v) {switch (v.getId()) {case R.id.login_btn://把登录事件封装成了一个方法,直接调用就行了,代码看起来简洁而且容易理解LoginEvent();break;}
}private void LoginEvent() {String username = username_et.getText().toString();String password = password_et.getText().toString();if (username.isEmpty() || password.isEmpty()) {Log.d(TAG, "账号或者密码不能为空");} else if (username.length() < 8 || password.length() < 9) {Log.d(TAG, "账号至少8位,密码至少10位");} else if (username.equals(USERNAME)) {if (password.endsWith(PASSWORD)) {Log.d(TAG, "恭喜你,登录成功");} else {Log.d(TAG, "登录失败->密码错误");}}
}

其他代码都没有变,我只是把登录事件封装到一个方法体里面了,这样封装一下,会很好理解,代码也就简洁了些。但是现在还有一个问题,如果点击事件很多,你必须要给每个点击事件封装一个方法,夸张点说,如果有100个点击事件,那我岂不是要在MainActivity里面封装100个方法吗?其实挺心疼MainActivity的,一个大姑娘家的,既要处理View层,又要处理业务逻辑层,把管家的事情都做了,能不憔悴吗,能有人喜欢吗


于是MVP架构就出现了,就是为了解决MainActivity大妹子的烦恼,首先我们需要定义一个接口,接口干嘛用的???(握了棵草,也不讲讲清楚,上来就接口!!!)没关系,我在代码中给你注释了,不怕你看不懂

public interface IMainView {//如果登录成功,管家会拨打这个电话(接口)void LoginSuccess();//如果登录失败,管家会拨打这个电话(接口),并告诉MainActivity大妹子为什么登录失败void LoginFailed(String msg);
}

然后我们让MainActivity实现这个接口

public class MainActivity extends Activity implements OnClickListener, IMainView {private static final String TAG = "MainActivity";public static final String USERNAME = "wuzhanglao";public static final String PASSWORD = "470782682";private EditText username_et;private EditText password_et;private Button login_btn;private MainPresenter mainPresenter;@Overrideprotected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);setContentView(R.layout.activity_main);initView();}private void initView() {username_et = (EditText) findViewById(R.id.username_et);password_et = (EditText) findViewById(R.id.password_et);login_btn = (Button) findViewById(R.id.login_btn);login_btn.setOnClickListener(this);//雇一个叫main的管家,然后把自己登录成功和登录失败的联系方式给他//如果登录成功,管家会拨打loginSuccess这个电话//如果登录失败,管家会拨打logniFailed(String msg)这个电话mainPresenter = new MainPresenter(this);}@Overridepublic void onClick(View v) {switch (v.getId()) {case R.id.login_btn:String username = username_et.getText().toString();String password = password_et.getText().toString();// 让自己的管家去处理登录事件mainPresenter.login(username, password);break;}}@Overridepublic void LoginSuccess() {Log.d(TAG, "管家打电话过来说:登录成功");}@Overridepublic void LoginFailed(String msg) {Log.e(TAG, "管家打电话过来说:登录失败,失败原因:" + msg);}
}

看到没有,我们的大妹子在onclick点击事件里面让自己的管家来处理登录事件,而自己只需要关心有没有登录成功,这样就显得轻松许多


我们看看大管家是怎么来做事情的

//MainActivity的管家
public class MainPresenter {private static final String TAG = "MainPresenter";private IMainView view;public MainPresenter(IMainView view) {this.view = view;}// Main管家处理登录逻辑public void login(String username, String password) {if (username.isEmpty() || password.isEmpty()) {view.LoginFailed("账号或密码不能为空");} else if (username.length() < 8 || password.length() < 9) {view.LoginFailed("账号至少8位,密码至少9位");} else if (username.equals(MainActivity.USERNAME)) {if (password.endsWith(MainActivity.PASSWORD)) {// 登录成功,main拨打loginSuccess()电话通知主人登录成功了view.LoginSuccess();} else {// 登录失败,main拨打loginFailed()电话通知主人登录失败了,并告知失败原因view.LoginFailed("密码错误");}}}
}


</pre><pre>

大管家会处理登录事件,然后把处理结果告诉大妹子,让大妹子根据不同的结果来进行不同的操作


最后给你看一下项目的结构



好了,MVP设计模式就介绍到这里了,如果有看不懂的同学,可以在下方留言,我会给你解答的。看了我的博客,就学会了MVP的同学,可以点个赞啊,收藏下奋斗奋斗

这篇关于菜鸟级教程:MVP是啥玩意儿的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/475121

相关文章

C#集成DeepSeek模型实现AI私有化的流程步骤(本地部署与API调用教程)

《C#集成DeepSeek模型实现AI私有化的流程步骤(本地部署与API调用教程)》本文主要介绍了C#集成DeepSeek模型实现AI私有化的方法,包括搭建基础环境,如安装Ollama和下载DeepS... 目录前言搭建基础环境1、安装 Ollama2、下载 DeepSeek R1 模型客户端 ChatBo

JAVA集成本地部署的DeepSeek的图文教程

《JAVA集成本地部署的DeepSeek的图文教程》本文主要介绍了JAVA集成本地部署的DeepSeek的图文教程,包含配置环境变量及下载DeepSeek-R1模型并启动,具有一定的参考价值,感兴趣的... 目录一、下载部署DeepSeek1.下载ollama2.下载DeepSeek-R1模型并启动 二、J

Vue项目的甘特图组件之dhtmlx-gantt使用教程和实现效果展示(推荐)

《Vue项目的甘特图组件之dhtmlx-gantt使用教程和实现效果展示(推荐)》文章介绍了如何使用dhtmlx-gantt组件来实现公司的甘特图需求,并提供了一个简单的Vue组件示例,文章还分享了一... 目录一、首先 npm 安装插件二、创建一个vue组件三、业务页面内 引用自定义组件:四、dhtmlx

MySQL zip安装包配置教程

《MySQLzip安装包配置教程》这篇文章详细介绍了如何使用zip安装包在Windows11上安装MySQL8.0,包括下载、解压、配置环境变量、初始化数据库、安装服务以及更改密码等步骤,感兴趣的朋... 目录mysql zip安装包配置教程1、下载zip安装包:2、安装2.1 解压zip包到安装目录2.2

Java使用Tesseract-OCR实战教程

《Java使用Tesseract-OCR实战教程》本文介绍了如何在Java中使用Tesseract-OCR进行文本提取,包括Tesseract-OCR的安装、中文训练库的配置、依赖库的引入以及具体的代... 目录Java使用Tesseract-OCRTesseract-OCR安装配置中文训练库引入依赖代码实

Ubuntu固定虚拟机ip地址的方法教程

《Ubuntu固定虚拟机ip地址的方法教程》本文详细介绍了如何在Ubuntu虚拟机中固定IP地址,包括检查和编辑`/etc/apt/sources.list`文件、更新网络配置文件以及使用Networ... 1、由于虚拟机网络是桥接,所以ip地址会不停地变化,接下来我们就讲述ip如何固定 2、如果apt安

PyCharm 接入 DeepSeek最新完整教程

《PyCharm接入DeepSeek最新完整教程》文章介绍了DeepSeek-V3模型的性能提升以及如何在PyCharm中接入和使用DeepSeek进行代码开发,本文通过图文并茂的形式给大家介绍的... 目录DeepSeek-V3效果演示创建API Key在PyCharm中下载Continue插件配置Con

Deepseek R1模型本地化部署+API接口调用详细教程(释放AI生产力)

《DeepseekR1模型本地化部署+API接口调用详细教程(释放AI生产力)》本文介绍了本地部署DeepSeekR1模型和通过API调用将其集成到VSCode中的过程,作者详细步骤展示了如何下载和... 目录前言一、deepseek R1模型与chatGPT o1系列模型对比二、本地部署步骤1.安装oll

在不同系统间迁移Python程序的方法与教程

《在不同系统间迁移Python程序的方法与教程》本文介绍了几种将Windows上编写的Python程序迁移到Linux服务器上的方法,包括使用虚拟环境和依赖冻结、容器化技术(如Docker)、使用An... 目录使用虚拟环境和依赖冻结1. 创建虚拟环境2. 冻结依赖使用容器化技术(如 docker)1. 创

Spring Boot整合log4j2日志配置的详细教程

《SpringBoot整合log4j2日志配置的详细教程》:本文主要介绍SpringBoot项目中整合Log4j2日志框架的步骤和配置,包括常用日志框架的比较、配置参数介绍、Log4j2配置详解... 目录前言一、常用日志框架二、配置参数介绍1. 日志级别2. 输出形式3. 日志格式3.1 PatternL