【问题标题】:Separation of Concerns in JavaFX GUIJavaFX GUI 中的关注点分离
【发布时间】:2018-08-13 14:50:38
【问题描述】:

情况

我正在开发一个 JavaFX 桌面应用程序,可以分为三个部分来描述:

  • 数据
  • 图形用户界面
  • 过程

GUI 是查看和编辑数据的一种方式,而该过程是一个需要数据执行其工作的过程。将 GUI 更多地视为允许用户自定义流程的补充部分。

鉴于性质,数据需要可写入存储,并且可由 GUI 读取。当然,我正在尝试

问题

假设我有一个“Person”类,其中包含 Name 和 Age 成员。为了将此对象数据绑定到视图,它必须包含表示数据的属性对象。这将使该类本质上是不可序列化的(这意味着我需要使用额外的代码对其进行序列化)。这也使类膨胀,感觉就像违反了关注点分离。

为了解决这个问题,我在 StackOverflow 上找到了一个相当标准的指南。 Applying MVC With JavaFx

该页面上的最佳答案建议使用 DataModel,它们基本上是模型的可观察版本。此外,它们可以具有“保存”和“加载”方法进行序列化。

这似乎是一个更好的解决方案,对于纯数据驱动的应用程序。然而,我的情况不同,因为即使我的应用程序是数据驱动的,它也非常实用(执行操作在后台)。

如果我使用传统的 DataModel,我需要确保 DataModel 可以转换为不可观察的模型,或者确保它们具有返回不可观察对象(如原语)中的所有数据片段的方法。代码的功能模块应该不需要识别和处理可观察的属性。

作为比较,我真的很喜欢 C# 具有本质上可观察的属性,并且非常适合 WPF。 C# 的方法允许我以两种方式使用数据,而无需与 observable 进行转换(当然也有例外!)。

问题

如何在这些选项之间做出决定?

  • 使我的模型可通过视图观察和可序列化,同时仍可用作具有原始 getter 和 setter 的基本模型。
  • 创建数据模型的中间步骤,数据模型是表示模型并绑定到视图的可观察对象。这些对象必须能够接受模型作为依赖项,然后再转换回模型(在被 GUI 修改之后)。

第一个选项是更少的代码。它所需要的只是每个原始成员的瞬态属性成员,以及用于序列化和反序列化的 2 种方法。但是,这感觉像是直接违反了关注点分离。

第二个选项是更多的代码,但它通过中间人(DataModels)将原始数据和 GUI 完全分离。对于我需要在视图中显示的每个对象,它都需要一个全新的类,以及与所述对象进行转换的方法!但是,感觉……“正确”。

我限制了这些选项之间的问​​题范围,以更好地适应 StackExchange。但是,我对任何和所有新观点都持开放态度!

这是一些示例代码

这是一个使用数据模型

的示例
class Person implements Serializable
{
    private String name;
    public String getName(){...}
    public void setName(){...}
}
class ObservablePerson //DataModel
{
    private StringProperty name;

    public ObservablePerson(Person person)
    {
        name = new SimpleStringProperty(person.getName());
    }

    public StringProperty nameProperty()
    {
        return name;
    }

    public Person toPerson()
    {
        ...
    }
}

这是一个没有数据模型的例子:

class Person implements Serializable
{
    private transient StringProperty name;

    public String getName(){ return name.getValue();}
    public void setName(String name){ this.name = new SimpleStringProperty(name); }

    public StringProperty nameProperty()
    {
        return name;
    }

    // 
    public void serialize()
    {
        //pseudocode
        write(name.getValue());
    }
    public void deserialize()
    {
        //pseudocode
        name = new SimpleStringProperty(readString());
    }
}

旁注

  • 应用程序的主要目的本质上是功能性的。它在后台执行操作。这是一个自动化工具。因此,数据(和 GUI)是对其功能的补充。 GUI 是一种自定义工具,而不是核心功能。
  • 应用程序中的所有数据都是可修改的,并且可以在 GUI 和 Process 中使用。因此,每条数据都需要能够从 GUI 中查看、序列化并以其最基本的格式使用。

【问题讨论】:

    标签: java user-interface model-view-controller javafx


    【解决方案1】:

    我花了相当多的时间才为类似的事情找出一个好的实施方案,但加班后我自己完成了。这是一个 3 年的项目,终于完成了,看起来很漂亮。

    我的建议是,回答问题的最佳方式是自己回答。您确切地知道您想要什么,以及您希望您的程序/服务器如何运行。

    对于可观察的实例,尝试制作单独的实例。一种用于在您的 GUI 上进行本地显示,另一种用于可串行通信的原因。

    对于操作机制,让线程按需并发执行以最大化其能力和功能,并确保在其他操作正在处理时没有组件冻结。特别是从服务器端。

    不要忘记安全性,大多数 Java 服务器都会在您的本地计算机上打开端口,这些端口可以远程访问。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2021-09-14
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2018-09-20
      • 1970-01-01
      相关资源
      最近更新 更多