MVP相对于MVVM在Android中的设计模式的缺点

9

你好,我正在阅读这篇文章https://news.realm.io/news/eric-maxwell-mvc-mvp-and-mvvm-on-android/,他们很好地解释了mvc、mvp和mvvm。我理解了mvp设计模式的工作原理。

我没有发现MVP相比MVVM有什么缺点。正如他们所建议的那样,这是一个问题:

Presenter Concerns -> Maintenance - 类似于控制器,Presenter易于随着时间的推移收集额外的业务逻辑,并混杂其中。在某个时刻,开发人员经常会发现自己拥有一个庞大而难以分解的Presenter。

有人能用例子解释一下它的含义以及如何使用MVVM解决它吗?

2个回答

11

我非常支持MVP,但实际上并没有尝试过MVVM。可能会出现Presenter失控的缺点是我有经验的,但可以加以缓解。

在本文的示例中,业务逻辑将相对简单。可能只需要处理一个模型,并且没有太多复杂的逻辑。

让我们考虑一个更复杂的例子。假设您有一个销售鲜花的应用程序。一旦用户选择了他们的一束花,他们将被带到订单选项屏幕,在那里他们可以:

  • 为鲜花添加留言
  • 选择礼品花瓶
  • 选择邮寄地址
  • 选择交货日期

然后添加一些领域要求:

  • 如果他们正在海外交付,则无法添加消息
  • 某些地区的交货时间有所不同
  • 某些花瓶仅与某些花卉配套使用

这可能不是最好的UX,但撇开这一点,现在您有一个Presenter必须处理许多不同的Models(帐户、地址、花瓶、订单),并且很快就开始承担许多超出仅告诉View显示什么和将事件传递给Model的职责。这违反了单一责任原则。同时,每当一个类开始超过500行时,我都会感到不安。

解决方案相对简单。您将所有不同的逻辑分离成UseCase类。我使用以下相对简单的基类:

public abstract class UseCase<I, O> {

    public static final int NO_STATUS = -1;

    public Observable<Integer> getStatus() {
        return Observable.just(NO_STATUS);
    }

    public abstract Observable<O> getAction(I input);
}
您可以在具体实现类的构造函数中指定输入输出类型,并注入所需的所有模型。 Presenter 获取来自 View 的事件和输入,将其传递给适当的 UseCase,然后使用 Model 进行复杂的逻辑处理,并将适当的数据返回给 Presenter 以更新 View。 如果需要更新 UI 状态,可以使用状态向 Presenter 发送定期状态更新。
这样,Presenter 就会重新成为在 View 和 Model 之间传输数据和事件的简单通道,而业务逻辑则被很好地包含在每个操作的单独类中。

谢谢Jahnold!“这可能不是最好的用户体验,但抛开这一点,现在你有一个Presenter需要处理许多不同的模型(帐户、地址、花瓶、订单),并且很快就可以承担许多职责,而不仅仅是告诉视图要显示什么并将事件传递给模型。”- MVVM如何解决这个问题? - N Sharma
我接受你的答案并授予奖励,但我的问题只回答了一半。非常感谢您分享有关MVP的知识。你能理解我最后一句话的意思吗?那就太好了 :) - N Sharma

5

正如在这篇文章中介绍的那样:

使用Android上的MVVM和Data Binding,可以更轻松地进行测试和模块化,并减少我们编写的连接视图+模型的粘合代码数量。

MVP和MVVM的主要区别有:

  • View层:在MVP中,您的View完全是一个笨拙而被动的View。但是在MVVM中,您的View更加灵活,因为它可以绑定到Observables(可观察对象)。
  • 在MVP中,由于View是愚蠢的,所以Presenter几乎负责一切,因此它会逐渐变得非常庞大和复杂。同时,在MVVM中,ViewModel受到View的支持(它稍微聪明一点:D),尤其是Data Binding,您可以减少一部分逻辑代码。
  • 因此,您需要编写很多Presenter代码,它们在逻辑上是相关的,并且您会发现很难将它们分解。

然而,许多开发人员更喜欢MVP,因为他们不希望某些业务逻辑代码成为XML布局的一部分。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接