Should i use builder pattern in DTO?
Asked Answered
I

1

12

This might be a pretty subjetive question, but i would to know some more opinions. I've built a Rest API service with Spring MVC, and i implemented the DTO-Domain-Entity pattern. I want to know what do you think about implementing the Builder pattern in DTOs, something like

public class UserResponseDTO
    extends AbstractResponseDTO {

    private String username;
    private Boolean enabled;

    public UserResponseDTO(String username, Boolean enabled) {
        this.username = username;
        this.enabled = enabled;
    }

    public String getUsername() {
        return this.username;
    }

    public Boolean getEnabled() {
        return this.enabled;
    }

    public static class Builder {

        private String username;
        private Boolean enabled;

        public void setUsername(String username) {
            this.username = username;
        }

        public void setEnabled(Boolean enabled) {
            this.enabled = enabled;
        }

        public UserResponseDTO build(){
            return new UserResponseDTO(username, enabled);
        }
    }
}

According to the definition:

The intent of the Builder design pattern is to separate the construction of a complex object from its representation. By doing so the same construction process can create different representations.

In most of my DTO cases (to not say all of them) i don't have a more complex object to build, such this case. And, honestly, i can't think of any example where construct a complex object if we are talking about DTOs.

One of the patterns which helps make immutable objects easier to use and to add clarity to code is the Builder pattern.

Builder pattern provides objects immutabiltiy. Then, we can think than a DTOs is the service response itself and should not be altered as this is a response (at least that is how i am thinking about it)


So what do you think? Should i use this pattern to DTOs (given the fact that this case, and probably most of them, does not satisfy the complex object principle)?

Instructive answered 4/8, 2015 at 20:3 Comment(5)
I wouldn't see the benefit of a builder or even a factory here. However, DTO's are often assembled by DTO assemblers, which are factories. I think the main motivation is the separation of concerns the DTO's responsibility is to be the data container while the assembler's responsibility is to well... assemble the DTO.Ventricose
I like builders. I like using them to create immutable objects. Problem with DTO's is that you can't make the class immutable (at least in our situation, it basically prevents the POJO-loving Hibernate from working.) I do sometimes add builders to my DTO objects, but my concern is that there's no way to enforce through code that they be used. Then you end up with people writing object creation logic in other places.Nefertiti
I wouldn't use Builders as a means to enforce immutability. It's probably easier to ship an interface that doesn't have setters. The implementation object will have private setters used when the bean is generated. Client code doesn't need access to the implementation class. Good point about Hibernate @Marvo.Lalla
That's just it. One doesn't use Builders to enforce immutability. But Builders are useful for forcing the correct instantiation of classes, and to avoid hard to read and use "telescoping constructors". But if you can't change the design of the class in a way that forces you to use the Builder (like making it immutable and providing a factory or builder) then it's possible someone unfamiliar with the code will write their own instantiation code. informit.com/articles/article.aspx?p=1216151&seqNum=2Nefertiti
Thank you all! I think i got itInstructive
S
25

My short answer is that it's a matter of preference. If you like the way that Builder Pattern works, apply it. For such a small case, I don't think it matters either way. My personal preference would be not to use Builder here as it doesn't seem to add much value.

My longer answer is that Builder Pattern is designed to facilitate easier configuration of complex objects without resorting to anti-patterns like telescoping constructor. In this case, you don't have an anti-pattern in either case; both options are relatively small and efficient.

While we're talking about preferences, though, I prefer a modified version of the builder pattern that uses a fluent interface; each method returns the instance of Builder so that the method calls can be chained together (rather than on separate lines). This is similar to the Java example in the article that you linked.

I'd modify your builder to look like this:

public static class Builder {

        private String username;
        private Boolean enabled;

        public Builder setUsername(String username) {
            this.username = username;
            return this; 
        }

        public Builder setEnabled(Boolean enabled) {
            this.enabled = enabled;
            return this;
        }

        public UserResponseDTO build(){
            return new UserResponseDTO(username, enabled);
        }
    }

Thus, using the builder would look something like this:

UserResponseDTO ur = new Builder().setUsername("user").setEnabled(true).build();

Again, just a matter of personal preference.

Spinule answered 4/8, 2015 at 20:16 Comment(1)
Nice. Fluent builder is a much cleaner pattern to use IMO.Tribade

© 2022 - 2024 — McMap. All rights reserved.