我正在尝试一边学习Android,一边进行了一些研究,并发现MVVM模式是我要走的路。我对WPF / XAML有所了解。但是,我确实对视图(活动/片段)如何膨胀有疑问。
这是我对设计模式的一般理解:
模型位于底层。该层将具有业务逻辑和实体。对于每个声明的实体,使用Room将一个表存储在SQLite数据库中。为了坚持封装,所有数据成员都是私有的,只能通过get()
方法访问。
数据访问层存储我的数据库和实体的DAO。据我了解,DAO是负责在视图模型和数据库之间进行交互的对象。
视图模型是显示数据的方式。由于数据库将在存储库中引用,因此它将与存储库交互以最终访问数据库。
我遇到麻烦的地方是视图模型和视图关系。我了解,视图模型不了解视图,但是视图如何膨胀?我知道这是不正确的-但我的想法是,如果您使用DataBinding将例如onClick
属性绑定到ViewModel中的方法,并且假设此方法负责显示Dialog,则ViewModel具有View知识,因为它负责创建对话框。
从本质上讲,我的问题是,在扩大视图时,开发人员如何遵循MVVM范例?如果ViewModel不应该负责与View相关的任何交互,而仅要公开其数据,那么我是否缺少另一层桥梁来弥补通货膨胀?
答案 0 :(得分:0)
我所做的是将视图呈现逻辑(对话,吐司,小吃店等)抽象化,例如Presenter
(不要与MVP
Presenter
混淆)。然后,交互由ViewModel处理,而实际的 display 由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测试相当容易地进行测试。不利的一面是,如果您需要扩展点击行为以添加更多逻辑(验证之类的东西),这将无法扩展。然后,您将开始查看视图中的业务逻辑。
因此,除了最简单的视图之外,我建议所有人都采用第一种方法。
希望有帮助!