1
\$\begingroup\$

Following up on this question DTO interfaces for implementing web service integration I came up with this implementation.

Data Transfer Object interface following a java.util.Map protocol. The implementation uses Guava's ForwardingMap.

public interface Dto<K, V> extends Map<K, V> {}

public class DtoImpl<K, V> extends ForwardingMap<K, V> implements Dto<K, V> {

    private final Map<K, V> delegate;

    @Override
    protected Map<K, V> delegate() {
        return this.delegate;
    }

    private DtoImpl(final Map<K, V> map) {
        this.delegate = map;
    }

    public static <K, V> Dto<K, V> of(final Map<K, V> map) {
        return new DtoImpl<K, V>(map);
    }
}

Mapper interface between a type T and a Dto.

public interface Mapper<T> {

    public <K, V> Dto<K, V> toDto(T obj);

    public <K, V> T fromDto(Dto<K, V> dto, Class<T> clazz);
}

public class MapperImpl<T> implements Mapper<T> {

    public <K, V> Dto<K, V> toDto(T obj) {
        ObjectMapper objectMapper = new ObjectMapper();
        Map<K, V> map = objectMapper.convertValue(obj, Map.class);
        return DtoImpl.of(map);
    }

    public <K, V> T fromDto(Dto<K, V> dto, Class<T> clazz) {
        ObjectMapper objectMapper = new ObjectMapper();
        T obj = objectMapper.convertValue(dto, clazz);
        return obj;
    }

}

Comments and improvements on this implementation are welcome! Is it worth it to define the Mapper interface with something like interface Mapper<T, K, V>? Ideally I would like to say interface Mapper<T, S extends Dto<K, V>> but this is not possible or is it?

\$\endgroup\$
1
\$\begingroup\$

public interface Dto<K, V> extends Map<K, V> {} why don't you use simply a Map? Again, it is the same discussion related to marker interfaces we already had in your original question.

I'd define Mapper in the following way:

public interface Mapper<T, K, V> {
    public Dto<K, V> toDto(T obj);
    public T fromDto(Dto<K, V> dto);
}

I don't understand the reason why you need MapperImpl. What you need are concrete classes imlementing your interface for your specific types.

Imagine you want to map a Date to a Map<String,Integer>. You need something like this:

class DateMapper implements Mapper<Date, String, Integer>
{
    public Dto<String, Integer> toDto(Date date)
    {
        Dto<String, Integer> dto = new Dto<String, Integer>();
        dto.put("Day", date.Day());
        dto.put("Month", date.Month());
        dto.put("Year", date.Year());
    }

    public Date fromDto(Dto<String, Integer> dto)
    {
        return new Date(dto.get("Year"), dto.get("Month"), dto.get("Day"));
    }
}

I think that at this point you might be thinking at how you could obtain an instance of DateMapper. I think you should use some sort of factory or build it using reflection depending on what is better in your use case.

|improve this answer|||||
\$\endgroup\$
  • \$\begingroup\$ I just found out that my Dto interface is an anti-pattern ibm.com/developerworks/java/library/j-jtp02216/index.html. In your implementation you are programming against a concrete type Dto (which you didn't provide an implementation for) but isn't it better to code against interfaces? I guess your intention is to replace Dto by java.util.Map. \$\endgroup\$ – dmz73 Oct 5 '14 at 7:58
  • \$\begingroup\$ The intention of my MapperImpl was to provide a skeletal implementation of the Mapper interface that can map a generic POJO to a Map using a library such as Jackson. It should be able to map most value objects automatically like the DateMapper you showed. \$\endgroup\$ – dmz73 Oct 5 '14 at 8:01
  • \$\begingroup\$ @dmz73 Apart from your Dto interface being bad or not, it does not implement the antipattern that link talks about. Look at the specific example. \$\endgroup\$ – abuzittin gillifirca Oct 16 '14 at 6:14
  • \$\begingroup\$ @mariosangiorgio I'd define Mapper in the following way: You need to elaborate why your definition is better. \$\endgroup\$ – abuzittin gillifirca Oct 16 '14 at 6:18

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.