tags:

views:

255

answers:

2

In the Java code I'm working with we have an interface to define our Data Access Objects(DAO). Most of the methods take a parameter of a Data Transfer Object (DTO). The problem occurs when an implementation of the DAO needs to refer to a specific type of DTO. The method then needs to do a (to me completely unnecessary cast of the DTO to SpecificDTO. Not only that but the compiler can't enforce any type of type checking for specific implementations of the DAO which should only take as parameters their specifc types of DTOs. My question is: how do I fix this in the smallest possible manner?

+12  A: 

You could use generics:

DAO<SpecificDTO> dao = new SpecificDAO();
dao.save(new SpecificDTO());
etc.

Your DAO class would look like:

interface DAO<T extends DTO> {
    void save(T);
}

class SpecificDAO implements DAO<SpecificDTO> {
    void save(SpecificDTO) {
        // implementation.
    }
    // etc.
}

SpecificDTO would extend or implement DTO.

johnstok
Thanks. At first I couldn't quite see it, but after having a few arguments with the compiler, it all became clear.
A: 

Refactoring to generics is no small amount of pain (even though it's most likely worth it).

This will be especially horrendous if code uses your DTO interface like so:

DTO user = userDAO.getById(45);

((UserDTO)user).setEmail(newEmail)

userDAO.update(user);

I've seen this done (in much more subtle ways).

You could do this:

public DeprecatedDAO implements DAO
{
    public void save(DTO dto)
    {
        logger.warn("Use type-specific calls from now on", new Exception());
    }
}

public UserDAO extends DeprecatedDAO
{
    @Deprecated
    public void save(DTO dto)
    {
        super.save(dto);
        save((UserDTO)dto);
    }

    public void save(UserDTO dto)
    {
        // do whatever you do to save the object
    }
}

This is not a great solution, but might be easier to implement; your legacy code should still work, but it will produce warnings and stack traces to help you hunt them down, and you have a type-safe implementation as well.

davetron5000