samedi 3 novembre 2018

How to write generic Java API without method Overloading

I have 2 (or more), datasources which store the same thing; and I want to write an interface with methods to find items in them. Example:

public interface CarFinder {    
    public Car findById(String id);
}

Then I can write a class like this and use it:

public class CustomCarFinder implements CarFinder {

    public Car findById(String id) {
        ...
        return someCar;
    }
}
...
Car aCar = customCarFinder.findById("1");

CustomCarFinder knows how to connect to the datasource and retrieve the Car for me. The problem is that whereas for my first datasource, the CustomCarFinder can get a connection to it every time I call "findById"; for the second datasource it is the client to the CarFinder that knows how to get the connection, not the CarFinder. To supply the connection information to CarFinder I wrote something like this:

public interface CarFinder {

    public Car findById(String id, Object... context);

}

public class CustomCarFinder implements CarFinder {

    public Car findById(String id, Object... context) {
        //The Varargs (context) are not used in this version
        ...
        return someCar;
    }
}

public class AnotherCustomCarFinder implements CarFinder {

    public Car findById(String id, Object... context) {
        //Extract the connection here from the Varargs
        CustomConnection connection = (CustomConnection)context[0];
        ...
        //Somehow I find the car via this CustomConnection thing
        return someCar;
    }
}
...
Car aCar = customCarFinder.findById("1");
Car anotherCar = anotherCustomCarFinder.findById("1", aCustomConnection);

You see I used varargs so that I can use either or version of the API. In the first case where the connection does not have to be supplied I can still use:

Car aCar = customCarFinder.findById("1");

and if I need to supply the connection then:

Car anotherCar = anotherCustomCarFinder.findById("1", aCustomConnection);

Is there another way of doing the same thing? I am getting pushback ( from colleagues ), on the use of Varargs, that I should just overload the "findById" method with the different types of Connection types. I am resisting this, because I don't want the interface to reflect the types of datasources I am connecting to. I want the interface, if at all possible to remain:

public Car findById(String id);

I also don't like the Varargs, but I am not sure how to get rid of them and still accomplish what I want.

Aucun commentaire:

Enregistrer un commentaire