MVP瘦身方案的可行性

本文探讨了MVP架构在大型项目中可能导致大量接口代码的问题,提出通过使用Message进行通信来简化View层与Presenter层的交互,以此减少代码量。作者分享了一种改进方案,通过在Presenter中定义方法并利用封装的Message对象,使得View层只需处理handleMessage方法。该方案旨在平衡业务粒度划分与代码可读性,可行性有待进一步探讨。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

MVP瘦身方案的可行性

自google发布mvp架构demo以来,越来越多的人开始在项目中尝试使用mvp架构来搭建自己的项目。mvp的发布初衷也是为了将逻辑代码与UI分离,通过接口的方式互通,达到解耦的目的。但用着用着,我们会发现一个蛋疼的事实,因为mvp是通过接口的形式来互相通信,那么就无法避免地要额外写多个接口。

通常,一个Activity就对应着一个View、一个Presenter和一个Model,这就意味着有多少个Activity,就要多写至少2个接口。如果一个项目中有几十个上百个Activity,那么这增加的代码量可不容小觑,并且开发人员写起来也相当蛋疼。
贴一张现在项目某个module下presenter包结构图:

可以看到,光这里的presenter就多达20几个,相应地,model包跟ui包下也差不多都有20几个接口了。

mvp在项目中的实际操作

通常,我们是怎样定义mvp各个模块的接口的呢,拿用户端的接单DriverLocationAdvanceActivity来说:

model层:

View层:

presenter层:

可以看到,View层有三个网络请求的动作,具体的动作实施放在model层,model层通过CallBack接口回调将数据回传给presenter层,presenter层因持有view层的引用,因此调用view层的各个接口将数据传给具体的View完成具体动作的实施。

改进方案

view层与presenter层不通过接口,而是通过Message进行通信,这样就可以减少view层跟presenter层的代码量,并且可以重用presenter.
还是拿上面的例子,修改后的类结构图:

view层:

presenter层:

model层基本不变。

可以看到,view层中,在IView中增加了一个handleMessage方法,它接收一个Message对象,而presenter层中在每个方法中也都传入了Message对象,那这个Message有是什么呢?


import android.os.Build;
import android.os.Bundle;
import android.os.Handler;
import android.os.Looper;
import android.os.Messenger;
import android.os.Parcel;
import android.os.Parcelable;
import android.text.TextUtils;

/**
 * Defines a message containing a description and arbitrary data object that can be
 * sent to a {@link Handler}.  This object contains two extra int fields and an
 * extra object field that allow you to not do allocations in many cases.
 * <p>
 * <p class="note">While the constructor of Message is public, the best way to get
 * one of these is to call {@link #obtain Message.obtain()} or one of the
 * {@link Handler#obtainMessage Handler.obtainMessage()} methods, which will pull
 * them from a pool of recycled objects.</p>
 */
public final class Message implements Parcelable {
    /**
     * User-defined message code so that the recipient can identify
     * what this message is about. Each {@link Handler} has its own name-space
     * for message codes, so you do not need to worry about yours conflicting
     * with other handlers.
     */
    public int what;

    /**
     * arg1 and arg2 are lower-cost alternatives to using
     * {@link #setData(Bundle) setData()} if you only need to store a
     * few integer values.
     */
    public int arg1;

    /**
     * arg1 and arg2 are lower-cost alternatives to using
     * {@link #setData(Bundle) setData()} if you only need to store a
     * few integer values.
     */
    public int arg2;


    public String str;

    /**
     * 记录presenter的类名,当一个页面需要持有多个Presenter时使用
     */
    public String presenter;

    /**
     * An arbitrary object to send to the recipient.  When using
     * {@link Messenger} to send the message across processes this can only
     * be non-null if it contains a Parcelable of a framework class (not one
     * implemented by the application).   For other data transfer use
     * {@link #setData}.
     * <p>
     * <p>Note that Parcelable objects here are not supported prior to
     * the {@link Build.VERSION_CODES#FROYO} release.
     */
    public Object obj;


    public Object[] objs;

    /**
     * Optional Messenger where replies to this message can be sent.  The
     * semantics of exactly how this is used are up to the sender and
     * receiver.
     */
    public Messenger replyTo;

    /**
     * Optional field indicating the uid that sent the message.  This is
     * only valid for messages posted by a {@link Messenger}; otherwise,
     * it will be -1.
     */
    public int sendingUid = -1;

    /**
     * If set message is in use.
     * This flag is set when the message is enqueued and remains set while it
     * is delivered and afterwards when it is recycled.  The flag is only cleared
     * when a new message is created or obtained since that is the only time that
     * applications are allowed to modify the contents of the message.
     * <p>
     * It is an error to attempt to enqueue or recycle a message that is already in use.
     */
    /*package*/ static final int FLAG_IN_USE = 1 << 0;

    /**
     * If set message is asynchronous
     */
    /*package*/ static final int FLAG_ASYNCHRONOUS = 1 << 1;

    /**
     * Flags to clear in the copyFrom method
     */
    /*package*/ static final int FLAGS_TO_CLEAR_ON_COPY_FROM = FLAG_IN_USE;

    /*packa
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

fastsy

打赏一份隆江猪脚饭吧

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值