Java 中的模型-视图-视图模型模式:分离 UI 和逻辑以获得更简洁的代码
也称为
- MVVM
模型-视图-视图模型设计模式的意图
Java 中模型-视图-视图模型 (MVVM) 模式的意图是通过将应用程序划分为三个相互关联的组件:模型、视图和视图模型,来实现 UI 逻辑、表示逻辑和业务逻辑之间的清晰关注点分离。
模型-视图-视图模型模式的详细解释及其真实示例
真实示例
考虑一个类似于组织烹饪节目的 MVVM 模式真实类比示例。在这种情况下
模型:表示食谱本身,包括烹饪菜肴所需的食材和步骤。模型纯粹是关于数据和烹饪菜肴的规则,但并不关心如何将这些信息呈现给观众。
视图:类似于烹饪节目拍摄的厨房场景,包括所有视觉元素,例如厨房的布局、食材的摆放和炊具。视图负责视觉呈现以及观众如何看到烹饪过程。
视图模型:就像烹饪节目的剧本一样,它解释食谱(模型)并组织节目的流程。它告诉厨师(视图)下一步显示什么,何时添加食材以及如何对更改做出反应,例如替换食材。视图模型弥合了食谱的技术细节和厨师的演示之间的差距,确保观众理解每个步骤,而无需深入了解食谱本身的复杂性。
在这个示例中,视图模型允许厨师专注于烹饪和与观众互动,而底层的食谱保持不变,从而促进了关注点之间的清晰分离。
通俗地说
MVVM 设计模式将应用程序划分为三个不同的组件:模型,它保存数据和业务逻辑;视图,它显示用户界面;以及视图模型,它充当中间人,将数据从模型绑定到视图。
维基百科说
模型-视图-视图模型 (MVVM) 是一种软件架构模式,它促进了图形用户界面 (视图) 开发(无论是通过标记语言还是 GUI 代码)与业务逻辑或后端逻辑 (模型) 开发之间的分离,从而使视图不依赖于任何特定的模型平台。
Java 中模型-视图-视图模型模式的编程示例
视图模型将保存业务逻辑并将数据从模型暴露给视图。
public class BookViewModel {
@WireVariable
private List<Book> bookList;
private Book selectedBook;
private BookService bookService = new BookServiceImpl();
public Book getSelectedBook() {
return selectedBook;
}
@NotifyChange("selectedBook")
public void setSelectedBook(Book selectedBook) {
this.selectedBook = selectedBook;
}
public List<Book> getBookList() {
return bookService.load();
}
/** Deleting a book.
*/
@Command
@NotifyChange({"selectedBook","bookList"})
public void deleteBook() {
if (selectedBook != null) {
getBookList().remove(selectedBook);
selectedBook = null;
}
}
视图不包含任何逻辑,只有 UI 元素。
<zk>
<window title="List of Books" border="normal" width="600px" apply="org.zkoss.bind.BindComposer" viewModel="@id('vm') @init('com.iluwatar.model.view.viewmodel.BookViewModel')">
<vbox hflex="true">
<listbox model="@bind(vm.bookList)" selectedItem="@bind(vm.selectedBook)" height="400px" mold="paging">
<listhead>
<listheader label="Book Name"/>
<listheader label="Author"/>
</listhead>
<template name="model" var="book">
<listitem >
<listcell label="@bind(book.name)"/>
<listcell label="@bind(book.author)"/>
</listitem>
</template>
</listbox>
</vbox>
<toolbar>
<button label="Delete" onClick="@command('deleteBook')" disabled="@load(empty vm.selectedBook)" />
</toolbar>
<hbox style="margin-top:20px" visible="@bind(not empty vm.selectedBook)">
<vbox>
<hlayout>
Book Name : <label value="@bind(vm.selectedBook.name)" style="font-weight:bold"/>
</hlayout>
<hlayout>
Book Author : <label value="@bind(vm.selectedBook.author)" style="font-weight:bold"/>
</hlayout>
<hlayout>
Book Description : <label value="@bind(vm.selectedBook.description)" style="font-weight:bold"/>
</hlayout>
</vbox>
</hbox>
</window>
</zk>
要部署该示例,请转到 model-view-viewmodel 文件夹并运行
mvn clean install
mvn jetty:run -Djetty.http.port=9911
- 在浏览器中打开以下地址:http://localhost:9911/model-view-viewmodel/
何时在 Java 中使用模型-视图-视图模型模式
MVVM 适用于需要在用户界面和底层业务逻辑之间进行清晰分离的应用程序,尤其是在 UI 和业务逻辑独立变化的大型数据驱动应用程序中。这使得模型-视图-视图模型模式成为 Java 应用程序的理想选择。
模型-视图-视图模型模式 Java 教程
- Android 中的数据绑定 (developer.android.com)
- 模型视图视图模型 (MVVM) 简介 (GeeksforGeeks)
- 模式 - 使用模型视图视图模型设计模式的 WPF 应用程序 (Microsoft)
模型-视图-视图模型模式在 Java 中的真实应用
- 广泛用于 JavaFX 应用程序,用于桌面界面。
- 在 Android 开发中使用,使用 DataBinding 和 LiveData 等库进行响应式 UI 更新。
- ZK 框架 zkoss.org
- KnockoutJS knockoutjs.com
模型-视图-视图模型模式的优点和权衡
优点
- 由于业务和表示逻辑的解耦,提高了可测试性。
- 更轻松地维护和修改用户界面,而不会影响底层数据模型。
- 如果以通用方式设计,可以增强视图模型在不同视图中的可重用性。
权衡
- 在小型应用程序中,更简单的模式可能就足够了,因此复杂性会增加。
- 理解和正确应用该模式的学习曲线。
相关的 Java 设计模式
- MVC (模型-视图-控制器):可以将 MVVM 视为 MVC 的派生,它更强调绑定和解耦,其中视图模型充当中间人,与 MVC 中的控制器不同。
- MVP (模型-视图-表示器):与 MVVM 类似,但侧重于表示器处理 UI 逻辑,使 MVVM 的视图模型在直接 UI 操作方面更加被动。