Monday, April 02, 2007

< > Abstraction

I was refactoring some code last week and ran across a little section I thought was kinda neat. We had a method in some object that basically would try and get the next lowest item from a collection. Not the lowest, but the next lowest. There was also a method that did the exact same thing for the next highest item as well.

So basically if we had this collection { 2, 4, 5, 7, 9 } we would pass in one of those values to the method which would return the next lowest/highest. So if we called the next lowest function passing in '9' we would get '7' in return.

Here's the basics of the next lowest function

public Item GetNextLowest(Item item) {
Item result = null;
//Some other checking here
foreach (Item i in Values) {
if(i < item) {
//Set the result
if (result == null) result = i;
//There is a lower item, but make sure it's the next lower
else if (result > i) result = i;
}
}
return result;
}

Reversing the '< >' in the next higher function made the two methods identical so I needed a way to abstract this out. One way would be to pass some delegate in that did the comparison for you, but that would add a bunch of code elsewhere, and we're trying to shorten the amount of code. Another way would be to pass in a boolean and then do some if/else statements to determine if we want '<' or '>', but this adds unecessary logic that occurs quite often. So the solution that I finally implemented was this.

public Item GetNextLower(Item item) {
return GetNextItem(item, false);
}
public Item GetNextHigher(Item item) {
return GetNextItem(item, true);
}
public Item GetNextItem(Item item, bool higher) {
//Use this to figure out if we want < or >
int compare = (higher) ? 1 : -1;
Item result = null;
//Some other checking here
foreach (Item i in Values) {
if(i.CompareTo(item) == compare) {
//Set the result
if (result == null) result = i;
//There is a lower item, but make sure it's the next lower
else if (i.CompareTo(result) == compare) result = i;
}
}
return result;
}

So basically all that was added was the abstracted method and the 'compare' int that is used to determine if we wanted the next lower or higher Item.

No comments: