MVP模式的理解

最近看了些MVP的例子,谈谈自己的理解。水平不够,所以本文写的是一些理解的概念

我们设计的代码应该遵守单一职责原则,也就是一个类干一件事。而当View(Activity或Fragment、下文中的View都是指这俩货)和Model(即数据提供者)总是死缠烂打的纠结在一起,那代码看起来就会欲仙欲死。而MVP是一个用于强拆View与Model之间孽缘的有力工具。

开始接触鬼知道MVP是啥,管他三七二十一,先看看再说。这么多人推荐使用的MVP(Google推荐),总不会坑我,多学点东西也没坏处。

废话不多说,先上一张网上偷的图


MVP模式结构

图中有我们重点关注3个东西:

  1. View

    身份:Boss
    职责:给用户提供交互界面,对用户的操作作出回应
    简介:作为Boss,啥我都不管。交给我的管事Presenter就行了只要能体体面面的在外面装逼就行了。

  2. Presenter

    身份:管事
    职责:给View办事的直系下属,所有View要办的事都交给他
    简介:Boss的事儿太多啦,我一个人可忙不过来,找几个小弟(Model)来跑腿儿吧。我只需要把结果告诉Boss就行了。

  3. Model

    身份:小弟
    职责:是Presenter的狗腿子,脏活累活都叫他干,干完还要通知Presenter结果。
    简介:之前MVC的时候,我还能跟BOSS说上几句话,现在彻底没戏了。f**k,活儿都我干,功劳全让那老家伙得去了。

上面是MVP主要的管理结构。当然,Model、View、Presenter之间还可以有些别的角色,好让整个管理机构更加完善。毕竟,公司越大,角色就越多。比如图中Model与Presenter之间,Presenter指向Model的时候,并没有直接指向View,而是指向一个圆圈。这个表示,Boss是很忙的,不能说Presenter你来汇报工作我就得在,有事儿找我的秘书(接口)吧,我已经调教好(implements)她了,我的事儿她该懂的都懂,不该懂的我也没告诉她,然后,你懂得。然后Presenter的汇报工作就面向秘书(接口)了。

当然,我们可以举一反三。Presenter心想,Boss配了秘书,我也想弄一个。于是,Presenter也调教了一个,只不过档次低了点。以后Model干完活别来找我了,爷可是有身份的人。

说了这么多,其中废话最多。咱们的行话可是:

Talk is cheap ,show me the code

是时候表演真正的技术了。

组织结构

首先是View的实现
IMainActivity就是操控UI变化的接口,由MainActivity实现,最终由Presenter来控制。

public interface IMainActivity {   
        public void showProgress();   
        public void hideProgress();    
        public void showBeatResult(String result);   
        public void showBuyResult(String result);   
        public void showZBResult(String result);
}

MainActivity的实现

public class MainActivity extends AppCompatActivity implements IMainActivity{   

       private PresenterMain mPresenter;   
       private ProgressBar progressBar;   
       private ImageView imageView;   
       private TextView textView;    

        @Override   
        protected void onCreate(Bundle savedInstanceState) { 
                super.onCreate(savedInstanceState);    
                setContentView(R.layout.activity_main);       
            //作为Boss,想要一个管事的,还不是new一个就行了       
            //然后将Boss自己实现的接口传给Presenter,
            //Presenter对结果的处理直接通过这个接口来实现        
                mPresenter = new PresenterMain(this);        
                progressBar = (ProgressBar) findViewById(R.id.progressBar);       
                imageView = (ImageView) findViewById(R.id.imageView);        
                textView = (TextView) findViewById(R.id.textView);   
 }   

            //Boss的日常  
       public void onClick(View view){      
            switch (view.getId()){            
                case R.id.btn_beat:                
                   mPresenter.beatSomeBody("牧狗");              
                   break;           
                case R.id.btn_buy_golden_chain: 
                   mPresenter.buyGoldenChain();               
                   break;            
                case R.id.btn_zhuang_bi:               
                   mPresenter.zhuangBi();                
                   break;       
             }    
       }    
        @Override
        public void showProgress() {        
                progressBar.setVisibility(View.VISIBLE);   
        }    
        @Override    
        public void hideProgress() {
                progressBar.setVisibility(View.INVISIBLE);    
        }    
        @Override   
        public void showBeatResult(String result) {
                textView.setText(result);     
                imageView.setImageResource(R.mipmap.beat_somebody);  
        }    
        @Override   
        public void showBuyResult(String result) {
                textView.setText(result);
                imageView.setImageResource(R.mipmap.golden_chain);            
        }    
        @Override
         public void showZBResult(String result) {
               textView.setText(result); 
               imageView.setImageResource(R.mipmap.u_can_u_up); 
         }

作为一个Activity,内部只有操控UI的方法。

然后是Presenter

Presenter的实现

IPresenter就是作为一名Presenter的自我修养了,由Presenter实现。
里面提供了作为Presenter因该有的一些方法
注意onDestroy()这个方法,用于当View销毁时,这个Presenter就没用了,毕竟老大死了,作为小弟的你怎么能苟活于世。(其实是如果Presenter不死的话,View就不会死,View不死的话,这块内存就测漏MemoryLeak啦;想想,当你以为你杀死了View,而结果是他一直活着。总有一天他会找你报仇的)

public interface IPresenter {
    public void beatSomeBody(String name);

    public void buyGoldenChain();

    public void zhuangBi();

    public void onDestroy();
}

另外提供了一个接口OnResultListner ,这个用于监听Model的返回信息。毕竟,Model到底把事儿办得怎么样,我得知道,然后才好向Boss汇报。

public interface OnResultListner {
    public void onBeatResult(String result);

    public void onBuyResult(String result);

    public void onZBResult(String result);
}

然后Presenter实现了上面俩接口

public class PresenterMain implements IPresenter, OnResultListner {

    private IMainActivity iMainActivity;
    private Model mModel;


    public PresenterMain(IMainActivity iMainActivity) {
        //Boss当然只能有一个
        this.iMainActivity = iMainActivity;

        //小弟想要几个就new几个
        mModel = new Model(this);
    }

    /*
    * Boss要打人啦
    * */
    @Override
    public void beatSomeBody(String name) {
        //正派小弟去打人,请boss耐心等待
        if (null != iMainActivity) {
            iMainActivity.showProgress();
            mModel.beatSombody(name);
        }
    }

    /*
    * Boss要买金链子
    * */
    @Override
    public void buyGoldenChain() {
        //正派小弟去买金链子
        if (null != iMainActivity) {
            iMainActivity.showProgress();
            mModel.buyGoldenChain();
        }
    }

    /*
    * Boss要装逼
    * */
    @Override
    public void zhuangBi() {
        //这个逼由小弟代您装了
        if (null != iMainActivity) {
            iMainActivity.showProgress();
            mModel.zhuangbi();
        }

    }

    @Override
    public void onBeatResult(String result) {
        iMainActivity.hideProgress();
        iMainActivity.showBeatResult(result);
    }

    @Override
    public void onBuyResult(String result) {
        iMainActivity.hideProgress();
        iMainActivity.showBuyResult(result);
    }

    @Override
    public void onZBResult(String result) {
        iMainActivity.hideProgress();
        iMainActivity.showZBResult(result);
    }

    /*
    * 当View挂了
    * presenter绝不独活
    * 解除与View的持有关系,然后坐等被GC回收
    * */
    @Override
    public void onDestroy() {
        iMainActivity = null;
    }
}

最后是搞事儿的Model

低调做人

同样,这是作为一个Model的基本素质,然后按这个素质招收小弟。

public interface IModelMain {
    public void  beatSombody(String name);

    public void  zhuangbi();

    public void  buyGoldenChain();
}

最后,找到了具有该素质的小弟

public class Model implements IModelMain{
    private OnResultListner onResultListner;
    private static Handler mHandler = new Handler();

    public Model(OnResultListner onResultListner) {
        this.onResultListner = onResultListner;
    }

    @Override
    public void beatSombody(final String name) {
        mHandler.postDelayed(new Runnable() {
            @Override
            public void run() {
                onResultListner.onBeatResult(
                       name + "已经被教训了一顿"
                );
            }
        },2000);
    }

    @Override
    public void zhuangbi() {
        mHandler.postDelayed(new Runnable() {
            @Override
            public void run() {
                onResultListner.onZBResult(
                         "装逼成功"
                );
            }
        },2000);
    }

    @Override
    public void buyGoldenChain() {
        mHandler.postDelayed(new Runnable() {
            @Override
            public void run() {
                onResultListner.onBuyResult(
                        "老大,您的金链子"
                );
            }
        },2000);
    }

}

我们用一个Handler来模拟了任务并做了延迟2s,实际情况可能是作为后台任务执行一些延时的任务。

效果图1
效果图1
效果图3

代码贴完,闪人。
源码地址 https://github.com/ysh666665/demo
参考博客 http://www.jianshu.com/p/9d40b298eca9

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 202,980评论 5 476
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 85,178评论 2 380
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 149,868评论 0 336
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,498评论 1 273
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,492评论 5 364
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,521评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 37,910评论 3 395
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,569评论 0 256
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,793评论 1 296
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,559评论 2 319
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,639评论 1 329
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,342评论 4 318
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 38,931评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,904评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,144评论 1 259
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 42,833评论 2 349
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,350评论 2 342

推荐阅读更多精彩内容