简体   繁体   中英

Java - Interface to allow implementations to specify parameter list

I have this case where I want to implement a suggestion service. This is supposed to be a service that users can call to retrieve suggestive values for certain, defined fields. Say I want a suggestions for a car and mobilephones. These fields are fixed and I can thus hardcode a method for each in the interface of the service.

However, the implementation of the actual service should be free to determine how it retrieves these suggestion. It might look into a file, it might call a webservice, whatever. For that, it should also be able to determine what parameters it needs to retrieve these suggestions. Some implementations might want more information, some might want less. The same for what it returns: Some implementations might return a single value, others multiple.

I want to reflect this in the interface of the service, so I write it like this:

public interface SuggestionService {
    SuggestionResult getCarSuggestion(final SuggestionCriteria criteria);
    SuggestionResult getMobilephoneSuggestion(final SuggestionCriteria criteria);
}

Both SuggestionResult and SuggestionCriteria are interfaces. Implementations of the SuggestionService can use their own implementations of these two interfaces to properly provide the functionality. This works very fine for return types, as I am allowed to narrow them in my method-implementations:

public class SuggestionServiceImpl implements SuggestionService {
    public CarSuggestionResult getCarSuggestion(final SuggestionCriteria criteria) {...}
    public MobilephoneSuggestionResult getMobilephoneSuggestion(final SuggestionCriteria criteria) {...}
}

The problem is that I cannot change the parameter type. If I do this in SuggestionServiceImpl

public CarSuggestionResult getCarSuggestion(final CarSuggestionCriteria criteria) {...}

Then I get a compile error. Which makes sense because I have now narrowed the interface that I am trying to implement by reducing the amount of allowed parameter-types. This is, for good reasons, not allowed.

However, I feel like the SuggestionServiceImpl should be able to tell users of it what parameters it actually needs - by specifying them in it's method signature. There is a weird conflict of interest here and I can't come up with a solution to solve this. One the one hand, I want to write and use an interface that actual implementations needs to implement. This way I can make sure that all implementations provide methods for retrieving the fields that I am interested in - in this case car and mobilephone. However, the implementations interface should be able to tell it's users exactly what parameters of what type it needs and not accept any generic list of parameters, putting it on the user to pass the correct ones. Is there any way to combine these two desires?

The signature is still an interface, there is no requirement for them to all be homogenised into similar looking calls when they are not.

public interface CarSuggester {
    Car getCarSuggestion(String param1);
}

public interface PhoneSuggester {
    List<Phone> getPhoneSuggestion(int param1, String param2);
}

public class SuggestionService implements CarSuggester, PhoneSuggester {
    ...
}

This let's you keep (and test) discrete suggesters with a simple Facade Pattern to roll them together into a single impl (up to you if you require discrete impls as well - suggest it might well be sensible)

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM