Let me explain the problem I am dealing with. I have a custom (jar) API that I use in my production code. This API contains an ENUM that looks as follows:
public enum Cars {
AUDI("BERLIN", "FRANKFURT", "HAMBURG", "MUNICH")
VW("BERLIN", "FRANKFURT"),
MERCEDES("HAMBURG", "MUNICH")
private final String[] cityNames;
Cars(String... cityNames) {
this.cityNames = cityNames;
}
public isCityNameAvailable(String cityName) {
for (String city : cityNames) {
if (cityName.equals(city)) {
return true;
}
}
return false;
}
}
This simple ENUM contains cars and cities where they are available. So far our production code logic works as follows:
- Receive a city name (Berlin).
- Go through all cars from ENUM
Cars.values()
one by one. - Build a list if cars which are available for provided city (Berlin)
- Return this list of cars (AUDI, VW)
The new requirement states that we need to add a new constraint dealer to the available cars. This means, additional to the city, a filter has to be applied based on the dealer where the car is available (can be purchased).
HOWEVER the dealer constraint can be applied for one or more cars. For example, only AUDI is suppose to be filtered based on city name and dealer. All other cars are always available (based on city) whether or not dealer is available or not.
Simple solution would have been; updating the enum as follows:
public enum Cars {
AUDI("COOL AUTOS", "BERLIN", "FRANKFURT", "HAMBURG", "MUNICH")
VW("ALL", "BERLIN", "FRANKFURT"),
MERCEDES("ALL", "HAMBURG", "MUNICH")
private String dealerName;
private final String[] cityNames;
Cars(String dealerName, String... cityNames) {
this.dealerName = dealerName;
this.cityNames = cityNames;
}
// rest
}
The code flow becomes:
- Receive city name and dealer name. (Berlin, JUMBO CARS)
- Go through all cars, get a list of cars based on city name (Berlin).
- Out of the two cars available in Berlin (AUDI, VW), AUDI is only available at "COOL AUTOS" which does not matches the constraint "JUMBO CARS"
- Remove it from the list.
- VW is available at
ALL
dealers; dealer name is therefore irrelevant. - Provide VW back.
Another example:
- Receive city name and dealer name. (Berlin, COOL AUTOS)
- Go through all cars, get a list of cars based on city name (Berlin).
- Out of the two cars available in Berlin, AUDI is only available at "COOL AUTOS" which matches the constraint.
- VW is available all
ALL
dealers. - Provide Audi and VW back.
Problem:
I don't like the solution. It is not flexible, today a filter needs to be build based on Distributor, City and Car relationship. Tomorrow it could be something else. I simply added a tight coupling in ENUM based on my new requirement.
Question
Is there are design pattern that I can use to enhance the functionality of ENUM so that I can add as many filters as i like without building logic into ENUM itself?
Enhancing the functionality also means the relationship between Cars, cities and (new) constraints?
EDIT
- Updated the description and code to clarify that dealer
!=
manufacturer. - This is a hypothetical example. Scenarios where one car becomes available in another city, or more cars become part of
ENUM
is not the issue of this question.