Skip to content

DTOs and Transformer

Frieder Reinhold edited this page May 28, 2021 · 2 revisions

DTOs in GUI

In the GUI layer JavaFX properties (props from here) are used, which have the advantage to be directly binded to the UI. Means, that changes in the property will be directly visible to the user. In the business layer we use pojos, that have the advantage to be lightweight, can be persisted and have no JavaFX dependency.

For both props and pojo Correo uses Lombok. Read more about Lombok here https://www.baeldung.com/intro-to-project-lombok and don't forget to install the Lombok plugin to your IDE. For IntelliJ or Eclipse take a look here: https://www.baeldung.com/lombok-ide

Always use builders to create or transform DTOs.

Transformation between GUI and business

As business is not allowed to access GUI namespaces, all transformers between props and pojos are inside GUI. Basically such transformers have static methods to transform between the two concepts. E.g. https://github.com/EXXETA/correomqtt/blob/develop/src/main/java/org/correomqtt/gui/transformer/MessageTransformer.java

Pojos

Basically Pojos have attributes only. Everything else is covered by Lombok. All business pojos are in org.correomqtt.business.model

@Getter
@Setter
@Builder
@NoArgsConstructor
@AllArgsConstructor
public class DummyDTO {
  private String topic;
  private Qos qos;
}

Additionally you might want to implement equals and hashCode or make use of the lombok @Data annotation.

If your DTO is designed to be written to a json file. E.g. for configuration you have to add these two annotations to be as compatible as possible:

@JsonInclude(JsonInclude.Include.NON_NULL)
@JsonIgnoreProperties(ignoreUnknown = true)

JavaFX Properties

While pojos are simple and alle the work is covered by Lombok, props needs some more explanation. Basically props are in org.correomqtt.gui.model and named like this SubscriptionPropertiesDTO (Technical name at first followed by PropertiesDTO). Such a properties dto will contain a JavaFX property for each attribute. For simple scalar types there are predefined properties like BooleanProperty, IntegerProperty or StringProperty which are implemented SimpleBooleanProperty, SimpleIntegerProperty or SimpleStringProperty. For complex types there is a generic version Property which is implemented by SimpleObjectProperty.

So a very simple prop will look like this. Basically we have topic and a qos, which is an enum.

@AllArgsConstructor
public class DummyPropertiesDTO {
  private final StringProperty topicProperty;
  private final Property<Qos> qosProperty;
}

Getters and Setters must be implemented to access the properties directly:

    public String getTopic() {
        return topicProperty.getValue();
    }

    public void setTopic(String topic) {
        topicProperty.setValue(topic);
    }

    public Qos getQos() {
        return qosProperty.getValue();
    }

    public void setQos(Qos qos) {
        qosProperty.setValue(qos);
    }

In order to allow collection ui elements to directly make changes visible we have to define an extractor:

    public static Callback<DummyPropertiesDTO, Observable[]> extractor() {
        return (DummyPropertiesDTO m) -> new Observable[]{
                m.topicProperty,
                m.qosProperty
        };
    }

Additionally we have to implement the builder as inner class:

    public static class DummyPropertiesDTOBuilder {

        private StringProperty topicProperty = new SimpleStringProperty();
        private Property<Qos> qosProperty = new SimpleObjectProperty<>();
    
        public DummyPropertiesDTOBuilder topic(String topic) {
            this.topicProperty.set(topic);
            return this;
        }

        public DummyPropertiesDTOBuilder qos(Qos qos) {
            this.qosProperty.setValue(qos);
            return this;
        }

        public DummyPropertiesDTO build() {
            return new DummyPropertiesDTO(topicProperty, qosProperty);
        }
   }