Wednesday 9 July 2008

A little refactoring that pleased me

The other day I had to change the Page classes method to getBadgeTag, and found the following. I did not like it because the logic seemed repetitive, and it was not very clear what as going on.


class PageBeforeRefactor {


public Tag getBadgeTag() {
Tag badgeTag = getBadgeTag(getImpliedSeries());
if (badgeTag != null) {return badgeTag;}
badgeTag = getFirstBadgeTag(getImpliedKeywords());
if (badgeTag != null) {return badgeTag;}
badgeTag = getImpliedContributor();
if (badgeTag != null) {return badgeTag;}
badgeTag = getBadgeTag(getImpliedBookSection());
if (badgeTag != null) {return badgeTag;}
badgeTag = getBadgeTag(getImpliedBook());
if (badgeTag != null) {return badgeTag;}
badgeTag = getFirstBadgeTag(getImpliedBlogs());
return badgeTag;
}

private Tag getBadgeTag(Tag tag) {
if (tag != null) {
return tag.getBadge()==null?null:tag;
}
return null;
}

private Tag getFirstBadgeTag(List tags) {
for (Tag tag : tags) {
if (!keywordClassifier.isFootballClub(tag) && tag.getBadge() != null) {
return tag;
}
}
return null;
}
}


It would of been easy to just add a new if statement to the method, but I wanted to try and make the code more readable and more descriptive of what it was doing. I ended up with this:


class PageAfterRefactor {

public Tag getBadgeTag() {
return new PriorityOrderedBadgeFinder()
.check(getImpliedBlogs())
.check(getImpliedSeries())
.check(getImpliedKeywords())
.check(getImpliedContributor())
.check(getImpliedBookSection())
.check(getImpliedBook())
.getBadgeTag();
}

class PriorityOrderedBadgeFinder {

Tag badgeTag;

public PriorityOrderedBadgeFinder check(Tag t) {
if(badgeTag == null && t!=null && !keywordClassifier.isFootballClub(t) && .getBadge()!=null) {
badgeTag = t;
}
return this;
}

public PriorityOrderedBadgeFinder check(List tags) {
for (Tag tag : tags) {
check(tag);
}
return this;
}

public Tag getBadgeTag() {

return badgeTag;

}
}
}


An added bonus to this refactoring was that I pulled some logic out the slightly bloated (100+ lines) page class. It could now be tested separately and I could shift 6 or so tests out of the PageTest class.

1 comment:

Ulf said...

Cool example, but there's a irritating fact. Your doing both refactoring and changing your business logic with the priority order. If you would fix that, the example would gain much more comprehensibility.

Blog Archive