1

The Situation

I'm developing a JavaFX desktop application that can be described in three parts:

  • The Data
  • The GUI
  • The Process

The GUI is a means of seeing and editing the data and the process is a, well, a process that requires the data to perform its job. Think of the GUI as more of a supplementary piece that allows a user to customize the process.

Given the nature, the data needs to be writable to storage, and readable by the GUI. Naturally, I'm attempting to

The Problem

Let's say I have a class "Person" with members for Name and Age. In order to databind this object to a view, it must contain Property objects representing the data. This will make the class inherently non-serializable (meaning I will need to serialize it with extra code). This also kind of bloats the class, which feels like a violation of Separation of Concerns.

To solve this problem, I found a fairly standard guide on StackOverflow. https://stackoverflow.com/questions/32342864/applying-mvc-with-javafx

The top answer on that page suggesting using DataModels, which are basically observable versions of your models. In addition, they can have "save" and "load" methods for serialization.

This seems like a better solution, for pure data-driven applications. My situation is different, however, because even though my application is data-driven, it is also very much functional (performs actions in the background).

If I use traditional DataModels, I will need to ensure the DataModels can either be converted into non-observable models, or make sure they have methods to return all the data pieces in non-observable objects (like primitives). The functional module of the code should not need to recognize and deal with observable properties.

As a comparison, I really like how C# has properties that are inherently observable, and fit very well into WPF. C#'s approach allows me to use the data in both ways without the need for conversions to and from observable (there are exceptions, of course!).

The Question

How do I decide between these options?

  • Making my models Observable by the Views AND Serializable while still functioning as basic models with primitive getters and setters.
  • Creating an intermediate step of DataModels, which are Observable Objects that represent the models and bind to the views. These objects would have to be able to accept the models as a dependency, and later be converted back into the models (after being modified by the GUI).

The first option is less code. All it requires is a transient Property member for every primitive member, as well as 2 methods for serializing and deserializing. However, it feels like a direct violation of Separation of Concerns.

The second option is more code, but it completely separates the raw data and GUI through a middleman (DataModels). It requires an entirely new class for every object that I need to display in a View, with methods for conversion to and from said object! However, it feels..... "Proper".

I am limiting the scope of the question between these options, to fit better with StackExchange. However, I am open to any and all new perspectives!

Here's Some Example Code

Here is an example with datamodels

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()
    {
        ...
    }
}

Here is an example without datamodels:

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());
    }
}

The main purpose of the application is functional in nature. It performs actions in the background. It's an automation tool. Therefore, the data (and GUI) is supplementary to its function. The GUI is a customization tool, not a core-feature.

  • 1
    This seems like a better solution, for pure data-driven applications. My situation is different, however, because even though my application is data-driven, it is also very much functional (performs actions in the background). --- Every practical application performs such actions, including the so-called data-driven ones. Are you sure you're not just suffering from a lack of imagination? Nothing prevents you from using the data-driven approach (which may handle 70 percent or more of your actual application's needs), while still performing custom/exotic functionality alongside. – Robert Harvey Mar 5 '18 at 18:35
  • @RobertHarvey What if I said that the application is purely functional, but can change its functionality slightly based on data that must be supplied by the user? There's absolutely nothing in which the user will see in the GUI that won't be used in the functional module (the GUI and editable data are more or less Quality of Life features). If your opinion remains the same, I can assume you're advocating the second option, tedious as it is, which is fine. I will likely end up attempting the data-driven approach if I don't get a good answer for my question. – Clay07g Mar 5 '18 at 18:45
  • @Clay07g, do your models need to be Serializable? If so, the Observable class approach might just work better for you. Less boilerplate code and custom serialization you have to worry about. Alternatively, instead of relying on Java Serialization, you could use JSON serialization which only needs your getters and setters. – Berin Loritsch Mar 5 '18 at 19:10
  • @BerinLoritsch Yes, serialization is a requirement. I agree that the Observable class route will reduce serialization code. As far as the method of serialization goes, I am restricted to using Serializable. Interestingly, as long as I don't store data in transient members, all of my data classes will not require any code for serialization. With the Observable class approach, all of the transient Properties are just temporary, and will be converted to their primitive versions before serialization, reducing serialization code, but adding conversion code. Thank you for your input. – Clay07g Mar 5 '18 at 19:15
  • I wish I could be of more help, but most of my UI experience is with C#. I haven't done Java GUIs in a decade. A few things have changed since then. JavaFx being one of them. – Berin Loritsch Mar 5 '18 at 19:20

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Browse other questions tagged or ask your own question.