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 违规的示例是 Context
:Context
的子类(例如 Application
和 Activity
)不等价。一些需要 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
的实现是 Activity
、Fragment
,或者,也许只是单元测试的模拟。
因此,您问题的完整答案是:一个演示者可以在不同的视图中重复使用,只要该演示者不依赖于视图的特定实现,而只依赖于它们的超级 class .
附加信息:
我猜你问这个问题是因为,一方面,你觉得一个演示者应该能够处理不同的视图(想想 A/B 测试不同的 UI),但是,另一方面,观点是 Activity
和 Fragment
的事实让你对这个想法感到不舒服。
我个人的看法是MVC/MVP中Activity
和Fragment
都不应该是观点。 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 的职责。
我有一个简短的问题。我正在尝试(并努力)使用 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 违规的示例是 Context
:Context
的子类(例如 Application
和 Activity
)不等价。一些需要 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
的实现是 Activity
、Fragment
,或者,也许只是单元测试的模拟。
因此,您问题的完整答案是:一个演示者可以在不同的视图中重复使用,只要该演示者不依赖于视图的特定实现,而只依赖于它们的超级 class .
附加信息:
我猜你问这个问题是因为,一方面,你觉得一个演示者应该能够处理不同的视图(想想 A/B 测试不同的 UI),但是,另一方面,观点是 Activity
和 Fragment
的事实让你对这个想法感到不舒服。
我个人的看法是MVC/MVP中Activity
和Fragment
都不应该是观点。 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 的职责。