MVC 及其派生的设计模式总是存在“10 人会找到 12 种实现方式”的问题,因此我将简要指出一些“流行”的实现方式。
到目前为止,常见的是您的“用户界面”肯定映射到 MVVM 中的“视图”。然后从这里开始有点值得商榷。
ViewModel 是大脑
实现 MVVM 的一种流行方式是“ViewModel”是整个应用程序的大脑。在这种情况下,“Application”映射到“ViewModel”,“Domain”映射到“Model”。 ViewModel 控制(并决定)获取数据的内容和方式,以及它想要向 View 公开的内容和方式。大多数时候“模型”只是一个普通的 POJO 类(例如IceCream 类)。
对于 JavaFX,您可以让 Model 和 ViewModel 中的所有属性由某种 Property 实现(即实现该接口的东西)表示。如果您没有使用“mvvmFX”之类的 API,那么您的视图很可能会将属性绑定到 ViewModel 中的其他属性。如果您使用的是“mvvmFX”(我没有使用),那么您(很可能)将通过属性名称将 View 属性绑定到 ViewModel(这是 WPF 所做的)。
在这种方法中,ViewModel 负责获取冰淇淋列表。 IceCreamService 可以被认为是一个单独的Service 层,或者您可以假设它是 ViewModel 的一部分(它本身不是 ViewModel,但它属于 ViewModel)。如果您想更新此列表,则由 ViewModel 决定。
模型作为域
另一个实现是让模型进行数据管理,很像 hibernate 在 Spring 中所做的。模型类继续表示数据(或实体等),但它带有自己的持久性逻辑。这意味着如果您更新 Model 对象的值(例如更改 IceCream 实例的风格),Model 会知道它是“脏的”,并将更改推送到存储库。
MVCVM
我还读到了另一个approach。简而言之,它类似于第一种方法,但它将IceCreamService 类移动到一个名为“Controller”的全新层中。
你的例子
根据您的示例,这是说明如何在 JavaFX 中实现它的示例。
class IceCreamSelectionView { // The FXML controller class used as MVVM View class
@FXML ComboBox<String> iceCreams;
@FXML ComboBox<String> flavors;
private final IceCreamSelectionViewModel vm; // The corresponding ViewModel
@FXML private void initialize() {
Bindings.bindContent(iceCreams.getItems(), vm.getIceCreams());
Bindings.bindContent(flavors.getItems(), vm.getFlavors());
vm.selectedIceCreamProperty().bind(iceCreams.valueProperty());
vm.selectedFlavorProperty().bind(flavors.valueProperty());
}
}
class IceCreamSelectionViewModel {
/*
* The properties
*/
public final ObservableList<String> getIceCreams() { return iceCreams; }
public final ObservableList<String> getFlavors() { return flavors; }
public final StringProperty selectedIceCreamProperty() { return selectedIceCream; }
public final StringProperty selectedFlavorProperty() { return selectedFlavor; }
private updateIceCreams() {
iceCreams.setAll(iceCreamService.getIceCreams());
}
}
// There is no Model class because both "iceCream" and "flavor" cannot be further broken down.