Search code examples
javaimmutabilitybuilderdto

How to produce immutable DTOs without explicitly using a constructor?


Suppose I have a DTO class:

public class SomeImmutableDto {

    private final String someField;
    private final String someOtherField;

    public SomeImmutableDto(String someField, String someOtherField) {
        // field setting here
    }

    // getters here
}

This is a nice immutable DTO. But what if I have 20 fields? It leads to the proliferation of a lot of unreadable constructors and unmaintainable code.

There is a solution for this problem however, the Builder pattern:

public class SomeImmutableDto {
    private final String someField;
    private final String someOtherField;

    private SomeImmutableDto(Builder builder) {
        // field setting here
    }

    public static class Builder {

        private String someField;
        private String someOtherField;

        // setters here

        public SomeImmutableDto build() {
          // building code here
        }
    }

    // getters here
}

Now I can do something like this:

SomeImmutableDto dto = new SomeImmutableDto.Builder()
    .setSomeField(/* ... */)
    *setSomeOtherField(/* ... */)
    .build();

Now I have an immutable dto which does not have an abundance of ugly constructors.

My problem is that I need a dto which has public setters AND immutable because there are some legacy code in the project which cannot be refactored at the moment and it requires the presence of public setters in order to initialize dto objects.

Is there some pattern which is usable here or this won't work? I'm thinking about the Proxy pattern but I'm not sure it can be applied in a way it is not looking like an ugly hack.


Solution

  • I think if you need to be legacy-code-compliant, the best way is to use a non modifiable wrapper just like in Collections.unmodifiableList method it is done.

    It is "hack", but I think it is forced by legacy code and it is "not so bad" :)