I have a couple of classes that are doing the same thing: filling a series of object using data sources passed as a parameter. As I need two distinct of them, my interface holds the following contract:

// Arbitrary names, didn't find a good name for the application field yet
public interface DataMapper<O>    {
     * Those two sources cannot be fused together, they come from
     * different places from another API
    public O mapData(DataSource first, DataSource second);

However, I have a problem. One legacy class from my program only uses the first out of two sources, and doesn't need the second. As it is the only one that needs only one out of two, I considered using the contract like this:

Output output = LegacyMapper.mapData(firstDataSource, null);

But this feel dirty to me: anyone else than me going through the code would have to ask me first Why is the second data source null, while the interface specifies that you need both ?.

So what are my options to create a proper design that won't feel too lame ?

1) Creating a second contract mapData(DataSource onlyData);, then setting the unused one as return null considering the implementation ?

2) Creating another interface specifically for the legacy mapper ?

3) Letting the code as-is and commenting it ?

Any help would be appreciated.

Thanks !

  • The use of generics seems strange here. It implies that every DataSource can be used to create objects of any type. If that's not the case, you probably want something like public O mapData(Supplier<? extends O> first, Supplier<? extends O> second); or similar
    – Caleth
    Feb 7 '18 at 10:43
  • You're right, that's another flaw that I did not take in account. It may be a good idea to change that as well, indeed ! Feb 7 '18 at 13:05

Create an interface DataConverter<O> which has method convert taking as parameter a DataSource and returns O.

public interface DataConverter<O>    {
     * Responsible for converting DataSource into useable type O.
    public O convert(DataSource datasource);

There is no reason to force DataMapper into the role of a converter, if all it is supposed to do is convert. I wouldn't even make DataMapper<O> derive from DataConverter<O>, as it seems to me that DataMapper<O> is about merging DataSources. However if you have reason to believe that it would be no loss of performance to convert to O and then merge two O instances, you could do this instead.

public interface DataMapper<O>    {
    public O mapData(O first, O second);

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.