我们认为该模型与MVVM(应用于JavaFX)一起使用是什么?

时间:2019-01-14 00:43:29

标签: oop javafx mvvm

我对如何在JavaFX中组织代码感到有些困惑(假设我打算采用MVVM的方式)。

考虑下面的标准4层体系结构图:

enter image description here

MVVM中的“模型”在哪里?它在“用户界面”层内还是在“应用程序/域层”上?我可以想象MVVM的模型是适合当前视图的后端模型的表示(投影),但是我不确定从网上看到的情况。

例如:

我有一个简单的冰淇淋应用程序。其应用层公开了以下方法:

  • IceCreamService.iceCreams(): List<String>;
  • IceCreamService.flavours(iceCream: String): List<String>

用户界面将具有一个带有冰淇淋列表的组合框,并根据用户的选择允许他选择一些口味。然后有一个按钮可以提交订单。

问题是:

我们认为这里的模型是什么?这是我们称为模型的IceCreamService还是模型将是我们在UI级别上由属性/可观察对象组成的类?如果是后者,谁负责用数据填充此模型? “控制器”(ViewModel)还是应该足够聪明才能自己执行(即,它对IceCreamService的引用?)

谢谢!

1 个答案:

答案 0 :(得分:2)

MVC及其派生的设计模式始终会出现“ 10个人会找到12种实现方式”的问题,因此我将简要指出一些“流行的”实现。

到目前为止,仍然常见的是您的“用户界面”肯定映射到MVVM中的“视图”。然后从这里开始值得商

ViewModel是大脑

实现MVVM的一种流行方法是“ ViewModel”是整个应用程序的大脑。在这种情况下,“应用程序”映射到“ ViewModel”,“域”类型映射到“模型”。 ViewModel控制(并决定)什么以及如何获取数据,以及什么以及如何将其公开给View。大多数情况下,“模型”只是一个普通的POJO类(例如IceCream类)。

对于JavaFX,您可以通过某种Property实现方式(即实现该接口的方式)来表示Model和ViewModel中的所有属性。如果您未使用“ mvvmFX”之类的API,那么您的View很可能具有绑定到ViewModel中其他属性的属性。如果您使用的是“ mvvmFX”(我没有使用过),那么(很可能)您将通过属性名称将View属性绑定到ViewModel(WPF就是这么做的)。

在这种方法中,ViewModel负责获取冰淇淋列表。 IceCreamService可以被视为单独的Service层,或者您可以假设它是ViewModel的一部分(它本身不是ViewModel,但它属于ViewModel)。如果要更新此列表,则由ViewModel来决定。

模型作为域

另一种实现是使Model进行数据管理,这与休眠状态在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.