So, as often happens, I encountered the following code at work:
@Override | |
protected boolean isPertinentFile(String filename) { | |
return filename.contains(ObjectType.FOOD.name()) || filename.contains(ObjectType.DRINK.name()) | |
|| filename.contains(ObjectType.FLOWERS.name()) || filename.contains(ObjectType.DRUGS.name()) | |
|| filename.contains(ObjectType.SANITARY.name()) || filename.contains(ObjectType.MEDIA.name()) | |
|| filename.contains(ObjectType.UTENSILS.name()) || filename.contains(ObjectType.PERSONAL_HYGIENE.name()); | |
} |
It's basically a zipped file, containing other zipped files, containing supermarket sales item data. This little bit of code just decides if a file should be parsed.
SonarLint quite rightly complained "Refactor this method to reduce its Cognitive Complexity".
And I quite quickly came up with the thought that it's really a list, where we can stop evaluating the list after the first match.
So, it becomes something like:
@Override | |
protected boolean isPertinentFile(String filename) | |
{ | |
ObjectType[] types = {ObjectType.FOOD, ObjectType.DRINK, ObjectType.FLOWERS, ObjectType.DRUGS, | |
ObjectType.SANITARY, ObjectType.MEDIA, ObjectType.UTENSILS, ObjectType.PERSONAL_HYGIENE}; | |
for (ObjectType objectType : types) | |
{ | |
if (filename.contains(objectType.name())) | |
{ | |
return true; | |
} | |
} | |
return false; | |
} |
But, of course we have streams now:
@Override | |
protected boolean isPertinentFile(String filename) | |
{ | |
return Stream.of(ObjectType.FOOD, ObjectType.DRINK, ObjectType.FLOWERS, ObjectType.DRUGS, | |
ObjectType.SANITARY, ObjectType.MEDIA, ObjectType.UTENSILS, ObjectType.PERSONAL_HYGIENE) | |
.anyMatch(objectType -> filename.contains(objectType.name())); | |
} |
It looks better, no?
It's a trivial example, but I like it.
Addendum
A colleague mentioned that I should do a bit of this differently. Move some more stuff into the enum.
The result becomes something like this:
public enum ObjectType { | |
DRINK(true), | |
FLOWERS(true), | |
DRUGS(true), | |
SANITARY(true), | |
MEDIA(true), | |
UTENSILS(true), | |
PERSONAL_HYGIENE(true), | |
FOOD(true), | |
ALCOHOL(false), | |
TOBACCO(false); | |
private final boolean pertinent; | |
ObjectType(boolean pertinent) { | |
this.pertinent = pertinent; | |
} | |
public boolean isPertinent() { | |
return pertinent; | |
} | |
} | |
@Override | |
protected boolean isPertinentFile(String filename) { | |
return Stream.of(ObjectType.values()) | |
.filter(ObjectType::isPertinent) | |
.anyMatch(objectType -> filename.contains(objectType.name())); | |
} |
Moving knowledge into the Enum, seems to be a better fit here.