常用Android架構(gòu)設(shè)計(jì)模式(二)MVP模式

前言#

昨天我們已經(jīng)了解了MVC模式,也大概分析一下MVC模式的優(yōu)點(diǎn)和不足紧卒,確實(shí)在android中MVC使用起來會(huì)有點(diǎn)怪怪的,于是出現(xiàn)了MVP模式。

MVP模式是MVC衍生出來的新模式涮拗,也是為了彌補(bǔ)MVC在設(shè)計(jì)上的不足之處,把Model和View進(jìn)一步解耦迂苛,提高代碼整體的維護(hù)性三热。

正文#

首先還是先來看一下架構(gòu)圖:

這里寫圖片描述

誒,從架構(gòu)圖上看三幻,跟之前的MVC已經(jīng)有了很明顯的不同就漾,可以總結(jié)一下幾點(diǎn):

1、Presenter作為媒介處于Model和View之間念搬,在中間進(jìn)行綜合調(diào)度抑堡,跟MVC相比,Presenter已經(jīng)不是一個(gè)簡(jiǎn)簡(jiǎn)單單的路人甲了朗徊,開始掌控全局首妖。

2、Model和View的耦合性變低爷恳,更加方便之后維護(hù)有缆。

ok,再來了解一下這三個(gè)分別承擔(dān)的任務(wù):

Model:處理要顯示的內(nèi)容(與MVC無變化)
View:負(fù)責(zé)界面上內(nèi)容的顯示
Presenter:負(fù)責(zé)整體的邏輯功能和顯示變化

概念我們已經(jīng)弄清楚了,還是要實(shí)際操作一下棚壁,那我們先準(zhǔn)備些什么呢杯矩?

MainModel:負(fù)責(zé)處理一些任務(wù)和運(yùn)算。
MainPresenter:負(fù)責(zé)整體的功能邏輯調(diào)度灌曙。
MainActivity:負(fù)責(zé)View具體的顯示工作菊碟。

發(fā)現(xiàn)了沒有?MainActivity扮演的角色已經(jīng)和MVC完全不一樣了在刺,現(xiàn)在是位于View層逆害,這個(gè)一定要注意,不要被兩種模式弄得一臉懵逼蚣驼。

按照我的習(xí)慣魄幕,還是先寫View層,MainActivity的代碼:

public class MainActivity extends AppCompatActivity implements View.OnClickListener{

    private MainActivityPresenter presenter;

    private TextView textView;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        textView = (TextView) findViewById(R.id.textView);
        textView.setOnClickListener(this);
        presenter = new MainActivityPresenter(this);
        presenter.startLoading();
    }

    public void setText(String text){
        textView.setText(text);
    }

    @Override
    protected void onDestroy() {
        super.onDestroy();
        presenter.onDestroy();
    }

    @Override
    public void onClick(View v) {
        presenter.showToast();
    }
}

沒有比這更簡(jiǎn)單的代碼了颖杏,MainActivity除了初始化View以外纯陨,功能邏輯都是調(diào)用的Presenter,例如留储,loading翼抠,onClick等等。

然后看看MainPresenter:

/**
 * Created by li.zhipeng on 2017/3/24.
 * <p>
 * MainActivity的Presenter層
 */
public class MainActivityPresenter extends BasePresenter implements OnCallbackListener {

    private MainActivity mainActivity;


    public MainActivityPresenter(MainActivity activity) {
        this.mainActivity = activity;
    }

    public void startLoading() {
        MainActivityModel.login("lzp", "lzp", this);
    }

    @Override
    public void onSuccess() {
        mainActivity.runOnUiThread(new Runnable() {
            @Override
            public void run() {
                if (checkActivityValid()) {
                    mainActivity.setText("Loading success");
                }
            }
        });
    }

    @Override
    public void onFailed() {
        mainActivity.runOnUiThread(new Runnable() {
            @Override
            public void run() {
                if (checkActivityValid()) {
                    mainActivity.setText("Loading failed");
                }
            }
        });
    }

    @Override
    public void onLoading() {
        mainActivity.runOnUiThread(new Runnable() {
            @Override
            public void run() {
                if (checkActivityValid()) {
                    mainActivity.setText("Loading...");
                }
            }
        });
    }

    public void showToast(){
        Toast.makeText(mainActivity, "屌爆了哦~~~", Toast.LENGTH_SHORT).show();
    }

    private boolean checkActivityValid() {
        return mainActivity != null;
    }

    @Override
    public void onDestroy() {
        mainActivity = null;
    }

}

也很簡(jiǎn)單获讳,定義了登錄login方法阴颖,并且處理MainModel處理之后的回調(diào),通知MainActivity改變顯示效果丐膝,還提供了剛才了的onClick事件調(diào)用的showToast()方法量愧,核心的邏輯都在Presenter中。

最后就是MainModel:

/**
 * Created by li.zhipeng on 2017/3/24.
 *
 *      MainActivity的Model
 */
public class MainActivityModel {

    /**
     * 提供模擬的網(wǎng)絡(luò)請(qǐng)求類
     * */
    public static void login(final String name, final String pwd, final OnCallbackListener callbackListener){

        new Thread(){
            @Override
            public void run() {
                callbackListener.onLoading();
                try {
                    Thread.sleep(2000);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }

                if (name.equals("lzp") && pwd.equals("lzp")){
                    callbackListener.onSuccess();
                }
                else{
                    callbackListener.onFailed();
                }
            }
        }.start();
    }
}

處理了login方法中具體的邏輯帅矗,于是最簡(jiǎn)單的MVP架構(gòu)到此結(jié)束偎肃。

與MVC相比,MVP更加扁平化浑此,三者關(guān)系是比較平等的累颂,就好像我們生活中的情景:

View:就是客戶,現(xiàn)在需要一批材料凛俱。
Model:就是工廠喘落,能夠生產(chǎn)View需要的材料
Presenter:中介,在兩者之間來回跑最冰。

Presenter對(duì)View說:你要想這批材料,你得給我提供一些證明稀火,例如你公司的資質(zhì)啊暖哨,資金啊,需要材料的規(guī)模啊,等等篇裁。

Presenter對(duì)Model說:這是個(gè)大活啊沛慢,幾百萬的訂單,你得按照規(guī)定好好生產(chǎn)啊达布,別整黃了团甲。

View只負(fù)責(zé)給Presenter提供證明,如果有問題黍聂,直接把Presenter叫過來躺苦,問問生產(chǎn)進(jìn)度(onClick)。

Model只負(fù)責(zé)生產(chǎn)产还,拿到Presenter的材料匹厘,讓我生產(chǎn)啥我就生產(chǎn)啥,干完一單是一單脐区,根本不需要和客戶商量愈诚,干完了把成果交給Presenter就OK了。

現(xiàn)在的demo是最簡(jiǎn)單的的MVP牛隅,實(shí)際上為了把功能模塊進(jìn)一步劃分炕柔,還有出現(xiàn)Presenterlmpl和ViewImpl,剝奪Presenter和View的完全自主權(quán)媒佣,就好像突然冒出兩個(gè)領(lǐng)導(dǎo)匕累,指揮Model和View去做事。

就只看看Presenterlmpl和ViewImpl的代碼:

/**
 * Created by li.zhipeng on 2017/3/28.
 *
 *      MainActivity 必要要提供的方法
 */

public interface MainView {

    void setText(String text);
}

/**
 * Created by li.zhipeng on 2017/3/28.
 *
 *      MainPresenter 要實(shí)現(xiàn)的功能
 */

public interface MainPresenter {

    void startLoading();

    void showToast();

    boolean checkActivityValid();
}

// 實(shí)現(xiàn)對(duì)應(yīng)的接口
public class MainActivity extends AppCompatActivity implements MainView, View.OnClickListener {...}

// 實(shí)現(xiàn)對(duì)應(yīng)的接口
public class MainPresenterImpl extends BasePresenter implements MainPresenter, OnCallbackListener {...}

這樣進(jìn)一步分離之后丈攒,如果要增加方法必須要先向領(lǐng)導(dǎo)申請(qǐng)哩罪,例如MainView添加一個(gè)新方法,然后下屬才能去做巡验,例如MainActivity具體去實(shí)現(xiàn)這個(gè)方法际插。

總結(jié)#

到此為止,MVP模式的介紹就結(jié)束了显设,我們來和MVC對(duì)比一下:

優(yōu)點(diǎn):
1框弛、Model和View進(jìn)一步解耦,方便擴(kuò)展和維護(hù)捕捂。
2瑟枫、代碼模塊分工更細(xì),presenter是整體的核心指攒,代碼的可讀性增強(qiáng)了慷妙。

缺點(diǎn):
1、代碼量又增加了T试谩Oダ蕖!

MVP確實(shí)彌補(bǔ)了MVC的一些缺點(diǎn)和不足,雖然也需要模塊劃分架馋,工作量是提高了不少狞山,但是邏輯性有了更清楚的思路,不會(huì)像之前一樣摻雜在一起叉寂。

下一篇萍启,來聊一聊MVVM還有其他的一些東西,綜合的聊一聊設(shè)計(jì)模式屏鳍。

源碼點(diǎn)擊下載

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末勘纯,一起剝皮案震驚了整個(gè)濱河市,隨后出現(xiàn)的幾起案子孕蝉,更是在濱河造成了極大的恐慌屡律,老刑警劉巖,帶你破解...
    沈念sama閱讀 221,198評(píng)論 6 514
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件降淮,死亡現(xiàn)場(chǎng)離奇詭異超埋,居然都是意外死亡,警方通過查閱死者的電腦和手機(jī)佳鳖,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 94,334評(píng)論 3 398
  • 文/潘曉璐 我一進(jìn)店門霍殴,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人系吩,你說我怎么就攤上這事来庭。” “怎么了穿挨?”我有些...
    開封第一講書人閱讀 167,643評(píng)論 0 360
  • 文/不壞的土叔 我叫張陵月弛,是天一觀的道長(zhǎng)。 經(jīng)常有香客問我科盛,道長(zhǎng)帽衙,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 59,495評(píng)論 1 296
  • 正文 為了忘掉前任贞绵,我火速辦了婚禮厉萝,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘榨崩。我一直安慰自己谴垫,他們只是感情好,可當(dāng)我...
    茶點(diǎn)故事閱讀 68,502評(píng)論 6 397
  • 文/花漫 我一把揭開白布母蛛。 她就那樣靜靜地躺著翩剪,像睡著了一般。 火紅的嫁衣襯著肌膚如雪彩郊。 梳的紋絲不亂的頭發(fā)上前弯,一...
    開封第一講書人閱讀 52,156評(píng)論 1 308
  • 那天舞肆,我揣著相機(jī)與錄音,去河邊找鬼博杖。 笑死,一個(gè)胖子當(dāng)著我的面吹牛筷登,可吹牛的內(nèi)容都是我干的剃根。 我是一名探鬼主播,決...
    沈念sama閱讀 40,743評(píng)論 3 421
  • 文/蒼蘭香墨 我猛地睜開眼前方,長(zhǎng)吁一口氣:“原來是場(chǎng)噩夢(mèng)啊……” “哼狈醉!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起惠险,我...
    開封第一講書人閱讀 39,659評(píng)論 0 276
  • 序言:老撾萬榮一對(duì)情侶失蹤苗傅,失蹤者是張志新(化名)和其女友劉穎,沒想到半個(gè)月后班巩,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體渣慕,經(jīng)...
    沈念sama閱讀 46,200評(píng)論 1 319
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 38,282評(píng)論 3 340
  • 正文 我和宋清朗相戀三年抱慌,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了逊桦。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點(diǎn)故事閱讀 40,424評(píng)論 1 352
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡抑进,死狀恐怖强经,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情寺渗,我是刑警寧澤匿情,帶...
    沈念sama閱讀 36,107評(píng)論 5 349
  • 正文 年R本政府宣布,位于F島的核電站信殊,受9級(jí)特大地震影響炬称,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜鸡号,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,789評(píng)論 3 333
  • 文/蒙蒙 一转砖、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧鲸伴,春花似錦府蔗、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 32,264評(píng)論 0 23
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至仲吏,卻和暖如春不铆,著一層夾襖步出監(jiān)牢的瞬間蝌焚,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 33,390評(píng)論 1 271
  • 我被黑心中介騙來泰國(guó)打工誓斥, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留只洒,地道東北人。 一個(gè)月前我還...
    沈念sama閱讀 48,798評(píng)論 3 376
  • 正文 我出身青樓劳坑,卻偏偏與公主長(zhǎng)得像毕谴,于是被迫代替她去往敵國(guó)和親。 傳聞我的和親對(duì)象是個(gè)殘疾皇子距芬,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 45,435評(píng)論 2 359

推薦閱讀更多精彩內(nèi)容