简体   繁体   中英

Should we have similar DTOs?

I have 2 dtos that are used differently, but they have similar fields. Eg, MyIdESDto uses info from MyIdDto . The latter object is built with data from the DB, while MyIdESDto is built from the ElasticSearch and completed with MyIdDto data.

In my opinion, there should be only 1 DTO, and the code set as many fields in the DTO as it wants. Other people say the MyIdESDto should extend MyIdDto. Other people agree with this implementation, saying that it won't break the code if some feature is deleted. Which one is better to use? Can you give me reasons of your choice?

    @Data
    @NoArgsConstructor
    @JsonInclude(JsonInclude.Include.NON_NULL)
    public class MyIdESDto {
      private String name;
      private Integer id;
      private Integer age;


     public MyIdESDto(MyDto dto) {
        this.name = dto.getName();
        this.id = dto.getId();
        this.aage = 42;
     }
}




@Data
    @NoArgsConstructor
    @JsonInclude(JsonInclude.Include.NON_NULL)
    public class MyIdDto {
      private String name;
      private Integer id;
   }

I would go with the current implementation, because of the same reason given by third group.

To me inheriting is not a good idea, because I don't see a is-a relationship here; they just have few similar, and somewhat related, properties.

Inheritance is a mean to express A is-a B . It is not meant as mean to prevent code duplication.

So, if you can find a meaningful explanation why MyIdEDto is also a MyIdDto - then inheritance is the natural fit. If not - then stay with two distinct classes.

On the other hand, sometimes pragmatism gives good guidance, too. So if the majority of your team finds the inheritance-solution to be "better" go for that.

In other words: this is really a "style" question. There is no "better", and no hard facts to go in either direction. Therefore: pick the solution that works best for the people responsible the code. Respectively for the people that are most affected by this decision (those two groups are not always identical).

DTOs are just sets of properties (ie no business logic). So the only duplication that you avoid by introducing a DTO hierachy, is duplication of setters and getters, which may result in several lines of code, but is not complex by itself.

If each DTO models a different concept, and both classes are not intended to be used in related code (where one could benefit from some OO abstraction), the the code setting as many fields as it wants makes difficult to follow which fields have been initialized at any time. (For instance, it is immediatly clear that MyIdDto does not have an age , but had we used MyIdESDto with age=0 , we would have to trace where does the DTO come from, in order to know if we can trust in the value of MyIdESDto.age ).

When faced with this issued, I usually think on the following way (which I agree, may be a bit controversial):

Duplicating code can, in some situations, keep software architectures clean and understandable. Duplicates can also be used to keep unreadable, complicated abstractions from entering the system(...) Code that is abstracted to address two or more similar but separately evolving requirements may be difficult to modify

“Cloning considered harmful” considered harmful: patterns of cloning in software.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM