If you use the Status
enum in your OrderDto
you couple it with your enitity. As a result you can easily change the API to clients if you make changes your entity layer.
Let's assume the OrderDto
is serialized using java object serialization to send it to a client. If the client deserializes it it needs the classes of the entity layer. This is usually not what you want.
If you serialize the OrderDto
via JSON, then the name of the enum is usually used. This means that if you make a change to the Status
enum in the entity layer. It immediately changes the JSON that is send to the client.
I would decouple it with another StatusDto
enum and map it in the transport layer (where the DTO resides) using a Map
. This would also make sense if the entity Status
is more fine-grained as the StatusDto
, E.g.
public class StatusMapper {
private Map<Status, StatusDto> toDto = new HashMap<>();
public StatusMapper(){
toDto.put(Status.PLACED, StatusDto.IN_PROCESS);
toDto.put(Status.CONFIRMED, StatusDto.IN_PROCESS);
toDto.put(Status.SHIPPED, StatusDto.IN_DELIVERY);
}
public StatusDto map(Status status){
StatusDto dto = toDto.get(status)
if(dto == null){
// default status or exception ?
}
return dto;
}
}
This mapping is easy to test. When using a switch instead of a Map
it's hard to test the default case.
EDIT
That's a lot of overhead compared to a simple switch statement. Why should the default be hard to test?
First I want to say that the following example is based on Java. Maybe there are languages that don't have that problem.
Let's assume you have defined the following enum:
public enum Status {
S1, S2, S3;
}
Often when you implement a mapping you have a one to one relationship between the source and the target values. Thus a mapping using a switch would look like this:
public String map(Status status) {
switch(status) {
case S1: return "State1";
case S2: return "State2";
case S3: return "State3";
default: throw new IllegalArgumentException("Unknown status");
}
}
Now try to write a test that covers the default case.
You can't pass a Status
enum that will execute the default case, because all enum values are covered by their cases. It is the nature of the default case that it is only executed when a new enum is added. But you can not add a new enum just for testing purposes. Subclassing is not allowed. An Enum is final. The default case is often added as a hint for a developer to remember that there is some work to do if a new enum is added.
You can't pass null
since it leads to a NullPointerException
(in Java), because the switch uses the ordinal value of the enum. You can see this in the bytecode.

With the Map approach I can pass null
. Since the map has no mapping null is returned and thus the 'default' is covered. Sure it is not exactly the same as if an unknown enum would be passed, but for me it is the best compromise to test it.