0

By Guard Statements I mean something similar to the first part of the function:

def doSomething(String something)
{
    // Guard Statement
    if(!something)
    {
        return false
    }

    // more stuff
}

Say you might have several parameters, maybe you need to log that the method was called with a null parameter, or maybe throw a specific exception.

Clarification: I've read that both Guard Statements and smaller functions are good design choices, but it seems like if you include Guard Statements your functions won't be small.

By smaller functions I'm referencing Robert C. Martin's smaller function suggestions in Clean Code.

I guess what I'm asking is it worth it to include Guard Statements in a function even though it makes the function longer. I understand the answer could very based on if it's a public API or private function, for this purpose it's not a private function but a service in a MVC application, so I guess that makes it public?

  • 8
    And what is the question? – cmaster - reinstate monica Jun 08 '15 at 20:01
  • 1
    Trivially, including guard statements increases the size of a method. Whether that makes something "not small" depends on your definition of "small" and how many guard functions you need. If you find yourself needing dozens of guard statements, I would tend to expect that something is wrong with your design. If you have repetitive code in your guard statements, you can obviously factor that out as well. – Justin Cave Jun 08 '15 at 20:05
  • Recently I start using this coding style: converting those guard statements into "single line conditionals" as mentioned in Telastyn's answer. Example: ThrowIfBitmapNotGray8(bitmap), which subsequently calls ThrowIfBitmapNull(bitmap). In some cases, one can reduce the number of guard clauses down to one per argument, which I think is the minimum possible. Remember that there are other meaningful validations other than null checks. – rwong Jun 09 '15 at 12:05

4 Answers4

3

A few options:

  1. Don't use guards. Seriously, if a null parameter is going to blow up, just let it blow up. Also, while it's possible for some naughty programmer to call internal functions/services directly with bad data, you maybe don't need to guard everything.
  2. Single line conditionals. This is one place where a single like if(string.IsNullOrWhitespace(something)){ return; } is good. Keeps cruft out of the way.
  3. Sane defaults. something = something ?? string.Empty; (or similar) is much shorter, and in addition, it makes your function less fragile to bad input. Some people hate this though.
  4. Helpers. In C#, you can use expression trees to do something like Guard.Range(()=>x,1,10); which will throw while being more concise and more DRY.
  5. Don't care. "Small functions" can mean "less going on" in addition to "taking less space on the screen". The former is more important than the latter. While big space eating guards are annoying, they're easy to read. If you can get over that annoyance, then you can focus on what really matters - keeping your code easy to maintain by keeping the scope (not size) of functions small.
Telastyn
  • 109,398
  • 2
  • Private functions created internally during refactoring may not need guards if the class is properly designed, since they don't have an external API.
  • – Robert Harvey Jun 08 '15 at 20:13
  • @RobertHarvey - that'd fall under #1 for me, though I've gotten the argument in the past "sure, it doesn't have an external API now...". I think it's garbage, but I'm not sure how to refute it. I go YAGNI, they go "but input checking is good", I then exit the discussion and proceed to not check inputs on solidly internal functions. – Telastyn Jun 08 '15 at 20:15
  • If we're not going to bother unit testing our internal functions (i.e. "test the public API only"), I don't see why we should bother with guard functions either, unless and until such time that the function is made public for external consumption. – Robert Harvey Jun 08 '15 at 20:18
  • 1
    -1 if only for the statement of "Don't use guards." I will grant that some application domains don't necessarily need guard checks. But many functions should be written with a defensive mindset, and guard checks are an important element of that mindset. For the same reasons that we don't pass un-inspected elements into our SQL queries (thank you! Little Bobby Tables), guard checks provide an important step to ascertain that the passed data is clean and reasonably trustworthy. –  Jun 08 '15 at 22:12
  • @GlenH7 - I would argue that the goal isn't to inspect elements, but to make any input to a function be handled gracefully. Explicit, manual guard checks are one of the worst ways of doing that though.(#3 for example provides a common alternative) – Telastyn Jun 08 '15 at 22:29
  • I'd say use guards, but only at the most external layer, and only if you don't control all calling code (e.g. when you're making a web api or some dll you ship to customers/clients).bloating your business logic with null checks and guard clauses only makes testing harder and if you actually make an error in production code, just let it blow up – sara Mar 29 '16 at 07:09