Create helper methods to capture key concepts, even if they are only one line. Giving these concepts a meaningful name helps people reason about the rest of the code.
Consider this fragment of code, particularly the if test inside the loop:
public Course Find(string cde, bool throwIfMissing)
{
foreach(var c in _courses)
{
if (String.Equals(c.Code, cde, StringComparison.OrdinalIgnoreCase))
{
return c;
}
}
if (throwIfMissing)
{
throw new InvalidOperationException("Course not found");
}
return null;
}
While it’s easy to make the case that the test is easy to read, there are multiple issues to consider:
-
Any developer reader will need to reverse engineer intent from the code.
-
The policy of using
StringComparison.OrdinalIgnoreCase
for case comparison is widely repeated, opening the door for subtle defects due to inconsistencies. -
If the policy of case-insensitive code comparison ever changes, every occurrence of this will need to be changed.
To address this, introduce a helper method HasCode()
to do the test:
public bool HasCode(string code)
{
return String.Equals(Code, code, StringComparison.OrdinalIgnoreCase);
}
This localizes the policy of code insensitivity in one place, ensuring consistency across every use and giving one place for a change if ever required.
With this helper method, you can rewrite the original loop like this:
foreach(var c in _courses)
{
if (c.HasCode(cde))
{
return c;
}
}
Now the code reveals the intent more clearly - there is no need for a developer reading the code to reverse engineer what it means.
Comments
blog comments powered by Disqus