膨胀视图在MVVM设计模式中是如何工作的



我正在努力学习Android,我一直在做一些研究,并认为MVVM模式是我想要走的路线。我对WPF/XAML有些熟悉。然而,我确实有一个关于视图(活动/片段)是如何膨胀的问题。

这是我对设计模式的总体理解:

模型位于底层。该层将具有业务逻辑和实体。对于每个声明的实体,使用Room将一个表存储在SQLite数据库中。为了遵守封装,所有数据成员都是私有的,并且只能通过get()方法访问。

数据访问层存储我的数据库和实体的DAO。我的理解是,DAO是负责在视图模型和数据库之间进行交互的对象。

视图模型是数据公开的方式。它将与存储库交互以最终访问数据库,因为数据库将在存储库中被引用。

视图模型和视图关系是我遇到麻烦的地方。视图模型不理解视图,我理解,但视图是如何膨胀的?我知道这是不正确的,但我的想法是,如果您使用DataBinding将onClick属性绑定到ViewModel中的一个方法,并假设该方法负责显示对话框,那么ViewModel具有View知识,因为它负责创建对话框。

因此,本质上,我的问题是,当谈到膨胀视图时,开发人员如何坚持MVVM范式?如果ViewModel不应该负责任何与View相关的交互,只是为了暴露其数据,那么我是否缺少了另一层来弥补膨胀?

我所做的是将视图呈现逻辑(对话框、toast、小吃条等)封装在抽象中,比如Presenter(不要与MVPPresenter混淆)。然后交互由ViewModel处理,而实际显示则由View处理。

例如:

// "Presenter" class, say for a Dialog
public interface DialogPresenter {
void showDialog();
}
// View Model
public class ViewModel {
private final DialogPresenter mPresenter;
public ViewModel(DialogPresenter presenter)  {
mPresenter = presenter;
}
public void onButtonClick() {
// You can use DataBinding to bind this "onButtonClick()" method to
// the  button click, then trigger the showing of the dialog. You can
// add any other non-view related business logic as well. So there is
// no direct dependencies on Android view classes and this class is
// unit-testable by mocking out the presenter dependency.
mPresenter.showDialog();
}
}
// Fragment (the "View")
public View onCreateView(...) {
// View provides an implementation of the abstraction that will actually
// show the dialog
mViewModel = FragmentViewModel(new DialogPresenter() {
public void showDialog() {
// Show dialog in this fragment
}
});
}

这有点全面,但为您提供了视图模型与视图的分离,并使视图模型完全可以进行单元测试。缺点是你需要这个"中间人",但这通常是打破依赖关系和使事情更易于测试的折衷。

另一种选择是直接在视图中连接按钮逻辑:

// Fragment (the "View")
public View onCreateView(...) {
// Just wire everything up here and test via UI test (Espresso)
mBinding.button.setOnClickListener(new View.OnClickListener() {
public void onClick() {
// Show dialog
}
}
}

权衡的结果是,这显然更直接明了。使用UI测试可以很容易地测试这一点。不利的一面是,如果你需要扩展点击行为来添加更多的逻辑(验证或其他),这将无法扩展。然后,您将开始在您的视图中使用业务逻辑。

因此,对于除最简单的视图外的所有视图,我都推荐第一种方法。

希望能有所帮助!

相关内容

  • 没有找到相关文章

最新更新