Skip to content

Refactor data-carriers to record-classes. #184

@marcus-talbot42

Description

@marcus-talbot42

Various classes exist that function - or should function - solely as a data-carrier.

An example of such a class is the BeanPair-class:

public class BeanPair {

    private final Class<?> sourceClass;
    private final Class<?> targetClass;
    private boolean sourceStrict = false;
    private boolean targetStrict = false;

    public BeanPair(Class sourceClass, Class targetClass) {
        this.sourceClass = sourceClass;
        this.targetClass = targetClass;
    }

    public BeanPair withStrictSource() {
        this.sourceStrict = true;
        return this;
    }

    public BeanPair withStrictTarget() {
        this.targetStrict = true;
        return this;
    }

    public boolean isSourceStrict() {
        return sourceStrict;
    }

    public boolean isTargetStrict() {
        return targetStrict;
    }

    public Class getSourceClass() {
        return sourceClass;
    }

    public Class getTargetClass() {
        return targetClass;
    }

    public boolean matches(Class<?> currentSourceClass, Class<?> currentTargetClass) {
        return
                currentSourceClass.isAssignableFrom(sourceClass) &&
                        currentTargetClass.isAssignableFrom(targetClass);
    }

}

A more elegant solution could look something like the following:

public record BeanPair<S, T>(Class<S> sourceClass, Class<T> targetClass) {

    private static final String INSTANTIATION_FAILURE_MESSAGE = "Could not instantiate BeanPair. %s is null.";

    public BeanPair {
        Objects.requireNonNull(sourceClass, () -> INSTANTIATION_FAILURE_MESSAGE.formatted("Source-class"));
        Objects.requireNonNull(targetClass, () -> INSTANTIATION_FAILURE_MESSAGE.formatted("Target-class"));
    }

    public <U, V> boolean matches(Class<U> currentSourceClass, Class<V> currentTargetClass) {
        return
                currentSourceClass.isAssignableFrom(sourceClass) &&
                        currentTargetClass.isAssignableFrom(targetClass);
    }
}

Using this approach would cut down on boilerplate, introduce serialization-safety through the validation in the record-class' constructor, and adhere to the single-purpose principle. This would, however, require a different actor to hold the information regarding the strictness of the source and target. A good candidate for this responsibility would be the StrictMappingProperties-class. Incidentally, that class is also a candidate for refactoring to a record.

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions