Where do conditionals come from?

Given that we want to reduce the number of conditional branches in our code, I wonder whether it is possible to catalogue all of the reasons they exist, so that we might then in turn list a few ways to eliminate each category.


So to that end I’ve listed out those origins of conditionals that I could think of. Is this a fool’s errand? Possibly, but let’s give it a try anyway. Please comment if you can spot any that I have missed, and let’s see if we can grow a “complete” list…



Checking a value returned to me from code I own

This is the essence of the Null Check smell, and more generally Connascence of Meaning. For example, see this (intentionally bad) code from William C. Wake’s Refactoring Workbook:

public class Report {
public static void report(Writer out, List machines, Robot robot) throws IOException
{
//...

out.write("Robot");
if (robot.location() != null)
out.write(" location=" + robot.location().name());

if (robot.bin() != null)
out.write(" bin=" + robot.bin());

//...
}
}


Checking a value returned to me from code I do not own

For example, in Rails projects we often see code of this kind:

if User.exists?(:user_id => current_user.id)
# ...
else
# ...
end


Checking a parameter passed to me by code I own

Whenever I write a method that accepts a Boolean parameter, I open myself up to the Control Couple smell. Here’s an example from Piotr Solnica’s blog:

def say(sentence, loud = false)
if loud
puts sentence.upcase
else
puts sentence
end
end


Checking a parameter passed to me by code I do not own

Here’s an example from the jQuery documentation:




Checking my own state or attributes

Here’s an (intentionally bad) example from Martin Fowler’s Refactoring:

class Employee {
private int _type;
static final int ENGINEER = 0;
static final int SALESMAN = 1;
static final int MANAGER = 2;

Employee (int type) {
_type = type;
}

int payAmount() {
switch (_type) {
case ENGINEER:
return _monthlySalary;
case SALESMAN:
return _monthlySalary + _commission;
case MANAGER:
return _monthlySalary + _bonus;
default:
throw new RuntimeException("Incorrect Employee");
}
}
}


Checking a value I set previously in this method

For example:

public String format(List<String> items) {
StringBuffer s = new StringBuffer();
boolean first = true;
for (String item : items) {
if (first)
first = false;
else
s.append(", ");
s.append(item);
}
return s.toString();
}


Checking the type of an exception thrown by code I own

Here’s an example from the PHP language documentation:

getMessage(), "\n";
}

// Continue execution
echo "Hello World\n";
?>


Checking the type of an exception thrown by code I do not own

We often find code such as this in Rails controllers:

def delete
schedule_id = params[:scheduleId]
begin
Schedules.delete(schedule_id)
rescue ActiveRecord::RecordNotFound
render :json => "record not found"
rescue ActiveRecord::ActiveRecordError
# handle other ActiveRecord errors
rescue # StandardError
# handle most other errors
rescue Exception
# handle everything else
end
render :json => "ok"
end



Is this list anything like complete? Can it ever be?


I wonder if a useful next step might be to write down some general strategies for removing each of these kinds of conditonal…?


 •  0 comments  •  flag
Share on Twitter
Published on September 21, 2014 12:05
No comments have been added yet.


Kevin Rutherford's Blog

Kevin Rutherford
Kevin Rutherford isn't a Goodreads Author (yet), but they do have a blog, so here are some recent posts imported from their feed.
Follow Kevin Rutherford's blog with rss.