Reduce cognitive complexity when mapping

100 views Asked by At
if(obj.getAttribute() != null) {
    newobject.setAttribute(obj.getAttribute());
    }
if(obj.getAttribute() != null) {
        newobject.setAttribute(obj.getAttribute());
}
if(obj.getAttribute() != null) {
        newobject.setAttribute(obj.getAttribute());
}

Imagine this code at scale - mapping an object with 15+ attributes. How do I reduce cognitive complexity without splitting the mapping in two/three parts which increases the cognitive complexity overall.

2

There are 2 answers

1
IQbrod On BEST ANSWER

You might use Optional like

newobject.setAttribute(
    Optional.ofNullable(obj.getAttribute()).orElse("your_default_value")
);

But it depends of what should happen when obj.getAttribute() is empty ?
From what is provided newobject.attribute will be empty anyway, assigning property from parent does not require null-check.

0
k314159 On

You can use mapstruct, as the comment says. If, for any reason you don't want to (e.g. because mapstruct uses reflection, which can be slightly inefficient), then you can use a map.

Supposing you have two classes like this:

class A {
    Integer getAttribute1() { return null; }
    String getAttribute2() { return ""; }
}

class B {
    void setAttribute1(Integer x) {}
    void setAttribute2(String x) {}
}

Then you could define a map like this:

private static Map<Function<A, ?>, BiConsumer<B, Object>> mapOfAtoB = Map.of(
        A::getAttribute1, (b, x) -> b.setAttribute1((Integer) x),
        A::getAttribute2, (b, x) -> b.setAttribute2((String) x));

and use it like this:

void copyAtoB(A a, B b) {
    mapOfAtoB.forEach((fA, fB) -> {
        Object o = fA.apply(a);
        if (o != null)
            fB.accept(b, o);
    });