Reputation: 5090
I'm sure there must be a standard way to do this, but my attempts to search Stackoverflow have failed.
I have a method like:
public void processSomeWidgetsForUser(int userItemId) {
Iterator<Widgets> iter = allWidgets.values().iterator();
while(iter.hasNext()) {
Widget thisWidget = iter.next();
if (userItemId == -1 || thisWidget.getUsersItemId() == userItemId) {
widget.process();
}
}
}
As you can see -1 is a "special value" meaning process all. Doing this saves repeating the loop code in another method called processSomeWidgetsForAllUsers.
But I dislike special values like this because they are easy to misuse or misunderstand, which is exactly the situation what I'm having to fix now (where someone thought -1 meant something else).
I can only think of two ways to improve this.
Is there a better way? I'm sure I'm missing something obvious.
The above code has been changed slightly, so may not compile, but you should get the gist.
Upvotes: 2
Views: 78
Reputation: 5689
Although somewhat redundant, a fairly neat self-documenting approach could be to have 3 methods rather than one;
Make your original method private
, and make one small change which would be to add your static final int EXECUTE_ALL = -1
and use that in your original method, then add the two new methods;
public void processWidget(int wID) throws IllegalArgumentException {
if(wID == EXECUTE_ALL) throw new IllegalArgumentException();
originalMethod(wID);
}
public void processAllWidgets() {
originalMethod(EXECUTE_ALL);
}
It makes your class a little more cluttered, but as far as the exposed methods go, it is clearer and hopefully foolproof. You could alter it not to throw an exception and just ignore any invalid ids, that just depends on your situation.
This approach of course has the major downside that it changes how the class appears to other classes, breaking everything that currently uses the, now private, originalMethod().
Upvotes: 4
Reputation: 14192
You can change the method signature to accept a boolean for when you want to process them all.
public void processSomeWidgets(boolean doAll, int userItemId) {
Iterator<Widgets> iter = allWidgets.values().iterator();
while(iter.hasNext()) {
Widget thisWidget = iter.next();
if (doAll || thisWidget.getUsersItemId() == userItemId) {
widget.process();
}
}
}
This makes it more explicit, and easier to read in my opinion as there are no special values.
Upvotes: 1
Reputation: 82559
Have an external method like so:
static boolean idRepresentsAll(int id) {
return id == -1;
}
In this case, if you decide to replace it with a different mechanism, you only replace your magic number one place in your code.
At the very least, you would want to do something like this:
public static final int ID_REPRESENTING_ALL = -1;
Upvotes: 1
Reputation: 8981
Number 1 would work very nicely. Be sure to document what the variable is though, so future coders (possibly yourself) know what it means.
/**This is the explanation for the below variable*/
public final static int ALL_WIDGETS = -1;
Upvotes: 1