Sunday, 21 April 2019

Refactoring into Streams

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.

Friday, 12 April 2019

Some comments on blog comments

So, for a long time I've had comments enabled on this blog for anyone and without moderation.

And I did get a fair amount of spam comments about other websites, especially those polite bastards giving all that training in Chennai.

Stuff like this:

I have read your blog its very attractive and impressive. I like it your blog.

Java Training in Chennai Java Training in Chennai | Core Java Training in Chennai

And I've decided to turn on moderation to the max.

This means that any comments will be moderated by me, at my convenience.

So, if you're comment does not show up on the article in question right away, my most sincere apologies.

I will try and keep up.

Regards,