MVP Android - 有多少位主持人?

MVP Android - How many presenters?

我有一个简短的问题。我正在尝试(并努力)使用 MVP 设计模式设计我的应用程序。

我可以问一下,对于每个视图(activity,片段)我应该有一个单独的演示者class吗?

我可以在网上看到的资源不多,可以通过示例清楚地说明 MVP。谁有的话可以分享一下吗?

PS 我也在这个应用程序中使用了 RecyclerViewAdapter,所以任何关于这方面的建议都将不胜感激

提前致谢

模型-视图-控制器设计很早就出现在软件设计中,最初用于按钮元素等事物。您使用 MVP(基本上与 MVC 相同)以实现模块化且易于维护的架构,将表示与逻辑分开。

考虑到你的问题,我认为你确实希望每个视图有一个 Class。这将是最常见的方法。

http://antonioleiva.com/mvp-android/ 给出了 MVP 的理论概述。

虽然老了,但这是一个非常有趣的问题。由于现在 MVP/MVC/MVVM 在 Android 社区中有点像 "buzz-words",这个问题应该得到更完整的答案(恕我直言)。

简答:

单个演示者可用于多个视图

长答案:

一般来说,MVP/MVC 没有一个单一的定义 - 有许多方法可以实现这些架构模式。您没有提供 "your" MVP 的定义,因此我只能猜测您的想法。

也就是说,在面向对象编程中有一些 "best practices" 任何架构模式的任何实现都应该(理想情况下)考虑。

你问的是你是否可以在不同的视图中重用一个演示器实现,对吗?让我们通过SOLID原则的棱镜来看这个问题。

"L" 代表 Liskov 替换原则 (LSP)。它是 SOLID 中最容易被误解的原则之一,但该原则背后的总体思想如下:

LSP: if a piece of code works with object of class A, it should also work seamlessly with objects of any subclass of A (i.e. subclasses must be usable instead of A everywhere)

Android 中 LSP 违规的示例是 ContextContext 的子类(例如 ApplicationActivity)不等价。一些需要 Context 的代码可以与 Application 无缝工作,但是如果你传递 Activity,则会发生内存泄漏(这是 Android 应用程序中非常普遍的错误,它主要是由于 Google 的开发者违反了 LSP。

返回顶部你的问题。我假设您的演示者看起来像这样(注意视图的界面):

public class SomePresenter {

    /**
     * Views bound to this presenter must implement this interface
     */
    interface SomeView {
        void doSomething1();
        void doSomething2();
    }

    public void bindView(SomeView someView) {
        // view binding logic
    }

    // more presenter's methods

}

LSP 声明任何实现 SomeView 的 class 都可以与 SomePresenter 一起使用。演示者不应该关心传递给它的 SomeView 的实现是 ActivityFragment,或者,也许只是单元测试的模拟。

因此,您问题的完整答案是:一个演示者可以在不同的视图中重复使用,只要该演示者不依赖于视图的特定实现,而只依赖于它们的超级 class .

附加信息:

我猜你问这个问题是因为,一方面,你觉得一个演示者应该能够处理不同的视图(想想 A/B 测试不同的 UI),但是,另一方面,观点是 ActivityFragment 的事实让你对这个想法感到不舒服。

我个人的看法是MVC/MVP中ActivityFragment都不应该是观点。 post 总结了这一说法背后的原因:Why Activities in Android are not UI Elements.

我还建议您看一下 implementation of MVP in Android 的另一种方法 - 如果您使用这种方法,您会发现演示者应该能够处理不同的视图,而且你不会有这种 "something doesn't feel right".

的感觉

您的 Activity/Fragment 应该有 1 位演示者。 我喜欢让我所有的活动都从 BaseActivity 扩展,然后,我让这个 BaseActivity 需要一个 Presenter,看这个例子:

    public abstract class BaseActivity<Presenter extends BasePresenter> extends AppCompatActivity {

    protected Presenter mPresenter;

    @NonNull
    protected abstract Presenter createPresenter(@NonNull final Context context);

    @Override
    protected void onCreate(final Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        mPresenter = createPresenter(this);
        mPresenter.onCreate(savedInstanceState);
        }
    }
    // other lifecycle methods

然后,创建一个抽象的BasePresenter

public abstract class BasePresenter {

protected BasePresenter() {
}

@NonNull
public static BasePresenter nullPresenter(@NonNull final Context context) {
    return new BasePresenter() {};
}

@CallSuper
public void onCreate(@Nullable final Bundle savedInstanceState) {
}

现在,在创建 activity 时,请执行以下操作:

public class MyActivity extends BaseActivity<MyActivityPresenter>{


@Override
MyActivityPresenter createPresenter(@NoNull final Context context){
     return new MyActivityPresenter(all, Your, Dependencies, Here);
    }
}

现在观看 this video 并了解 MVP 中 Activity/View 的职责。