关于MVP,关于android,不得不说这篇博客已经来的非常晚了,这篇博客早就想写了,一直都在偷懒,就不给自己这么久的偷懒找借口了。尽管这篇文章po出来的比較晚。可是我所接触的程序猿一些朋友之类的,大家也是近期才開始听说mvp 。还没有真正的应用到项目中去。

14年年底的时候各大android的论坛博客,关于android的架构的思考越来越多,我也一直在关注,也在14年年底開始模仿着去写,事实上mvp,不算什么新的架构,都是做了非常多年的cs模式的应用的win开发人员,wpf开发人员玩烂了的东西。

mvp的概念什么的都不用说了。大家应该都看了非常多遍了,多说都是废话。

那么我们如今来在我们没接触到mvp之前大家都是用什么设计模式。開始。尽管非常多人喜欢说自己的项目是MVC,可是话说回来,what ,where ,why。

什么是MVC,你的项目里那里是controller,哪里是view。为何须要用mvc设计模式。

编程历史上各种书籍大家都喜欢用的3w的问法,看到了没,这次我也装了一手好B,hahaha。

1.what  什么是MVC?
mvc是一种设计模式。大多数web项目都是採用mvc的设计模式架构,thinkphp,asp.net,以及最新的razor引擎等等。详细的c v 关系什么的大家差点儿都能说的非常清晰,这个不用赘述。
2.where  你的项目里哪里是mvc给我解释下?
这个。。

 一般人都是这么回答: activity fragment就是view,model就是我json解析出来的javabean,对吧。可是,controller呢?wocao,好像没有controller。
3.why  为什么要用mvc设计模式?
一般人也说不清这个问题,非常多人都是回答,这是做项目必须要用的,这是代码的规范等等扯一堆无用的,反正回答的他自己也认为好像不正确。

这个问题一般要归结与设计模式的学习与应用。用过一些设计模式,对照好坏之后,你才知道为何须要设计模式,为什么要用设计模式,设计模式存在的意义是什么?  就一句话:为了将低代码耦合度。什么添加可读性的话,是靠你平时的代码风格,设计模式会提高一点可读性。可是 ,这也许不是基本的存在意义。

好了3W问题说完了。

我的总结是:14年往前,大部分android开发都是在用自己所谓的MVC ,可是多数人都找不到ctroller。是由于ctroller和view在一起了,从双方面来说这样的代码的缺点:
1.你这样不算是真正的mvc模式,
2.设计模式的目的在于解耦,这样肯定就代码耦合警告。

在thinkphp里,每个请求都是一个action。每个action最后都指向了一个controller,可是android中没有请求。android里是有action的,可是action的概念和web的action
又是两个概念。

android的源代码中,还是有一些mvc的,比方adapter就是一种 controller。
view就是act,frag,model那就不用说了。

而大家在2014年之前大家用的架构就是这样子。就是几个BaseActivity。BaseFrag,这样子,这样子是工厂模式。

问一下HOW?  对于android的本身的api,还有act生命周期这些,我们用mvc真的非常合适吗?  不合适,确切的和你说。那么,哪些设计模式更适合client的开发呢? 是mvvm。mvp 合适。

请看下一段:

话题说回“WHY”的问题。why 我们要用设计模式?是为了装B?no。我们为了减少代码耦合度。

综上所述,可得:设计模式用什么无所谓,仅仅要是适合自己的即可了,不要为了装逼忘记初心。哈哈哈,用词有点。

。。那么就是说,无论你用MVC,MVP。MVVM ,或者事mvvm的精简版MVM。亦或者是MVP精简版都行,解耦的目的达到了,也最大的节约了开发时间。 就好像谷歌官方建议我们放弃 getter setter方法一样,而是通过点属性直接訪问字段,使用getter
setter方法比使用点属性得到字段的速度要慢了一点点,尽管仅仅是一点点,可是循环多次就会又0.几秒的速度影响,放弃原来java的写法,用android更合适的方法去写代码,放手吧,CPU耗时永远比你的代码习惯重要。

回归文章的标题。我们来聊了聊MVP,我们把view和controller写到一起的写法已经受够了吧。有些页面非常大。我写过一个页面,公司没有产品经理,全然靠ui定页面,卧槽。非要把微信支付和支付宝支付还有其它一些复杂的推断都坐在一个页面。吊起支付client走完流程,回调回来。当中另一些回调回来的channel等等,还有回调状态的推断。卧槽,光这些,代码都够累的,还有其它的一些数据显示推断,好多网络请求。代码太多太杂了是吧
,caocaocaocao。
所以,还是mvp好点。详细mvp标准的代码的模式结构请自己去看其它博客。我的博客不想扯一些其它博客提过非常多遍的概念,view presenter的关系也不想再反复。这样仅仅能添加我这篇博客的字数而已。

那么问题来了。mvp有没有缺点呢?  
你是一个攻城狮 你看事物就要客观,你是一个程序猿你能够不客观。不要以为人家推崇他,你就崇拜它,必须正视这玩意的缺点,mvp最规范的写法非常麻烦,就算在我写过几十个规范的mvp应用的页面之后,我依然认为这货非常麻烦,尽管代码结构非常清晰,可是开发时间太长了,心累。

总结: mvp长处是会让代码机构清晰。缺点是减少开发效率。

话说怎么理解编程能力的好坏怎么表示, 我的理解编程就是解决这个问题。解决这个问题的速度和优雅度才是代表一个人的编程能力。

怎样既保证代码的结构清晰,又不减少开发速度呢? 回忆下我们之前学过用过的那些设计模式哪一种是加快开发效率的,又适用于这样的页面呢? 好像工厂模式的是这样子的,工厂模式就像工厂一样。生产效率非常高非常高,快到你想不到。  可是好像mvp的规范写法的话又不是非常好应用进来。caocaocao。android的view就是act跟其它平台比較不同。页面何时被释放你全然控制不了,activity基类的 结合好像不是非常好结合,presenter是能够大量生产出来,我也不想每次都在act中定义一个presenter的字段,这样好奇怪。那么这就难搞了。

。。

研究非常久。减少mvp的规范度,这个是能够考虑的,毕竟设计模式的目的就是为了减少耦合度不是为了装逼。没有必要非要严格遵守mvp, 能够减少mvp的规范程度来加速开发。  可是用工厂生产的方式的完美结合。不是非常好搞。

在之后的纠结中。有空就看下一些国外的框架搭建的方法,最后我在一个美帝的攻城狮的github下找到一种比較特别的mvp的体验,当中他有几句代码让我发现解决这个问题的诀窍。
以下贴我的终于的定版的样例代码:

1.这里是MainActivity。

public class MainActvity extends BaseCommActivity<MainPresenter> implements IMainView
{
@ViewInject(R.id.lay_main)
View lay_main; //android中本身一个layout不用于一些计算所以不须要在命名中提示类型像str_title这样的 你无论是RelativeLayout还是LinearLayout,一般仅仅是用于点击,所以统统以lay开头命名 无论类型
@Override
protected Class<MainPresenter> getPsClass() {
return MainPresenter.class;
}
@Override
protected int getLayoutId() {
return R.layout.activity_main;
}
@Override
protected void initAllWidget() {
lay_main.setOnClickListener(this);
}
@Override
protected void clickView(View v)
{
switch(v.getId()) {
case R.id.lay_main:
{
showMsg();
} break;
}
} @Override
public void showMsg() { //測试
toast("is showmsg methon");
}
}

2.请看IMainView

public interface IMainView extends IBaseCommView {
//在原有IBaseView 的初上加一个方法 要求MainActivity必须重载这种方法
public void showMsg();
}

3.MainPresenter

public class MainPresenter extends BaseCommPresenter {
//请求
private static final int REQ_GETAPPLIST_MSG = 0x002123;
private static final int RES_GETAPPLIST_MSG = 0x002124;
private final String SOFT_JP_FLAG = "soft_jp_flag";
private static final String CURRENT_PAGE = "current_page";
private static final String PAGE = "page_size";
private static final String SOFT_TYPE = "soft_type";
@Override
public void handMsg(Message msg) {
switch (msg.what) {
case REQ_GETAPPLIST_MSG: {
MainRequest req = new MainRequest();
req.put(SOFT_JP_FLAG, 2 + "");
req.put(SOFT_TYPE, 1 + "");
req.put("soft_jh_type", 0 + "");
String mac = WifiUtil.getMacAddress(iView.getActivity());
req.put(CURRENT_PAGE, 1 + "");
req.put(PAGE, 10 + "");
req.put("mac", mac);
req.setResPonseMsgWhat(RES_GETAPPLIST_MSG);
sendHttpPost(req, MainResponse.class);
iView.showProgressBar();
}
break;
case RES_GETAPPLIST_MSG:
{
iView.hideProgressBar();
if(msg.obj instanceof MainResponse)
{
MainResponse res=(MainResponse)msg.obj;
if(res.isSuc()) {
AppMainModel mainModel = res.getData();
iView.toast(mainModel.data.size() + "");
}
else{
iView.toast(res.getMsg());
}
}
}
break;
}
}
@Override
public void initData(Bundle saveInstnce) {
getHandler().sendEmptyMessage(REQ_GETAPPLIST_MSG);
}
}

能够看代码 activity中没有MainPresenter这个字段,仅仅是在getPsClass() 的时候返回的Presenter的类型。这个getPsClass() 的调用是在activity的基类里面写的。在基类中实例化了presenter,实例化之后。presenter会运行绑定IView。IView就是this了,基类的act在基类里的消息机制的处理方法直接传递到了presenter中运行了,所以,这样写Mainactivity写的代码就超级少了。

管理都在基类里面了。这样的写法真的好爽!哈哈哈!

presenter应该负责一些逻辑处理。这是毋庸置疑,可是 有些逻辑又须要activity的參与。这也会带来的问题事 有些逻辑是放在activity好还是presenter好。那么我们犹豫该放在哪里的时候。仅仅须要依据一点推断,act是 view,frag是view。他应该仅仅是负责一些控件,presenter是管理者,他就不要直接去管理view,这样子非常多东西就想通了。

可是android比較特别的是act。frag都有自己的生命周期,这就是android特别的地方。跟做站点后台的差别就拉开了。详细生命周期内的一些操作,就要看你的个人喜好去分配了。

假设你也在研究mvp的更好的方式,更好的使结构更清晰,更加加快开发速度,那你看下我的代码,找下是否有你须要,来解决你的一些困惑,我也是才疏学浅,希望大家多多指点相互学习。

 也许MVVM在数据绑定这块比mvp更适合,可是 mvp的自由行非常大有些细节还是须要你自己的去推敲。别人说的再好也仅仅是说个概念罢了。

代码挂在: https://github.com/weizongwei5/frame_mvp

PS:最后补充几句,事实上设计模式你玩的再好也仅仅是达到了解耦的目的。可是代码的可读性的问题还是须要你业余多多学习下好的写代码方式,不要明明都是 button1 button2  ,写switch case 1  case 2  case3  回头来看你的btn 看你的case  23456789
 鬼知道你表达什么意思,你个SB。多去分析下哪些开源的框架。既能懂得原理。学到知识。还能学习到好的代码风格。

就像 你看我的代码没在view  presenter中解析server返回的json一样。我都写在数据请求里面了,server本身返回的就应该做到非常标准,做到你不须要推断全都能够转model 。转java bean,这才是好的server开发人员。  view 和 presenter应该做他应该做的事情。不应该去负责json解析的这样的事情。我的swich case  也没用123456。而是用常量取代。  我不须要去为每个case写凝视,也能够清晰的看到这行代码就知道他表达什么意思。非常多代码风格还是要去细致推敲。
我不多说了。  

最后最后 补充上 我的公众号二维码。

挖掘更合适的MVP模式的架构设计的更多相关文章

  1. 架构C02-商业模式与架构设计

    商业模式与架构设计:A段架构与B段架构 <思考软件创新设计:A段架构师思考技术> A段架构师必须具备鲜活的创新思维,睿智的策略思考,犀利的洞察力和灵活的战术才能把握稍纵即逝的商机     ...

  2. VO(DTO)模式在架构设计中是否需要

    DTO(VO):也就是一般意义上的VO,封装后的对象.一般用于Web层—Service层间的数据传输入. PO:也就是一般概念上的Domain Object,如hibernate 中的Entity.一 ...

  3. Android APP架构设计——MVP的使用示例

    0. 前言 为了更好地进行移动端架构设计,我们最常用的就是MVC.MVP和MVVM,作为三个最耳熟能详的三大架构,应用可谓非常广泛.对于这三种架构设计以及优缺点已经在Android APP架构设计-- ...

  4. 使用 Unity 3D 开发游戏的架构设计难点

    Unity 3D 引擎对于开发者来说,入手非常快,因为它采用的是 C# 作为开发语言,这也大大降低了开发者的门槛.但凡只要懂一门编程语言的人都能使用 Unity 3D 引擎开发,另外 Unity 3D ...

  5. ABP架构设计交流群-上海线下交流会的内容分享(有高清录像视频的链接)

    点这里进入ABP系列文章总目录 ABP架构设计交流群-7月18日上海线下交流会内容分享 因为最近工作特别忙,很久没有更新博客了,真对不起关注我博客和ABP系列文章的朋友! 原计划在7月11日举行的AB ...

  6. MVC、MVP、MVVM架构模式

    MVC模式 如何设计一个程序的结构,这是一门专门的学问,叫做"架构模式"(architectural pattern),属于编程的方法论. MVC模式就是架构模式的一种,不仅适用于 ...

  7. MVC、MVP与MVVM架构模式

    MVC(Model View Controller): View 层是界面,Model 层是业务逻辑,Controller 层用来调度 View 层和 Model 层, 将用户界面和业务逻辑合理的组织 ...

  8. 如何结合整洁架构和MVP模式提升前端开发体验 - 整体架构篇

    本文不详细介绍什么是整洁架构以及 MVP 模式,自行查看文章结尾相关链接文章. 整洁架构粗略介绍 下图为整洁架构最原始的结构图: Entities/Models:实体层,官方说法就是封装了企业里最通用 ...

  9. [译]Google官方关于Android架构中MVP模式的示例

    概述 该示例(TODO-MVP)是后续各种示例演变的基础,它主要演示了在不带架构性框架的情况下实现M-V-P模式.其采用手动依赖注入的方式来提供本地数据源和远程数据源仓库.异步任务通过回调处理. 注意 ...

随机推荐

  1. 11scrapy

    一. Scrapy基础概念 Scrapy是一个为了爬取网站数据,提取结构性数据而编写的应用框架,我们只需要实现少量的代码,就能够快速的抓取.Scrapy 使用了 Twisted异步网络框架,可以加快我 ...

  2. 浅谈Link-Cut Tree(LCT)

    0XFF 前言&概念 Link-Cut Tree 是一种用来维护动态森林连通性的数据结构,适用于动态树问题.它采用类似树链剖分的轻重边路径剖分,把树边分为实边和虚边,并用 Splay 来维护每 ...

  3. 区间DP入门

    所为区间DP,主要是把一个大区间拆分成几个小区间,先求小区间的最优值,然后合并起来求大区间的最优值. 区间DP最关键的就是满足最优子结构以及无后效性!! 例如像是石子合并和括号匹配这两类比较经典的模型 ...

  4. 【转载】Sql语句用left join 解决多表关联问题(关联套关联,例子和源码)

    csdn中高手帮我给解决了,其实就是别名,给自己上了一堂别名的课,所谓别人是高手,其实就是自己是菜鸟吧! 表1:------------------------------ [人事表]     表名: ...

  5. mysql5.7配置

    my3306.cnf [client] port = 3306   #端口socket = /data/mysql3306/mysql3306.sock   #mysql以socket方式运行的soc ...

  6. 优化子查询sql语句为内连接

    背景: 希望提高查询的效率,从sql语句中频繁出现的子查询入手. 数据表如下:Student表中的CityCode对应于City表中的Code. Student表:                   ...

  7. Fidder详解-抓取HTTPS清求(Web/App)抓包分析(靠谱篇)

    为什么要学Fidder抓包? 学习接口,必须要学http协议,不要求您对协议的掌握有多深.只是希望你能够了解什么是协议.协议的报文.状态码等等!本文通过抓包工具Fidder带你进入接口的大门.我们通过 ...

  8. CDOJ 1218 Pick The Sticks

    Pick The Sticks Time Limit: 15000/10000MS (Java/Others)     Memory Limit: 65535/65535KB (Java/Others ...

  9. POJ3150:Cellular Automaton

    题意看不懂加题目想不通,很菜. n<=500个数围城环,每次操作对每个数Ai把与i在环上相距不超过d<n/2(包括Ai)的数加起来取模m<=1e6,求K<=1e7次操作后的环. ...

  10. 事件和委托: 第 6 页 .Net Framework中的委托与事件

    原文发布时间为:2008-11-01 -- 来源于本人的百度文章 [由搬家工具导入] .Net Framework中的委托与事件 尽管上面的范例很好地完成了我们想要完成的工作,但是我们不仅疑惑:为什么 ...