Versions Compared

Key

  • This line was added.
  • This line was removed.
  • Formatting was changed.
Comment: Migrated to Confluence 4.0

The Introduce Assertion refactoring recommends that if a section of code is going to make an assumption about the current state of the program, that an explicit assertion should check those assumptions first.

A common usage of this refactoring is to check that each method (and potentially each constructor) checks its preconditions using assertions. This is a particular form of defensive programming. Some argue that if you have sufficient tests in place, you don't need to apply defensive programming. For the small extra performance penalty, it seems like a small price to pay for extra resilience in our system.

Example

Suppose we have the following method:

Code Block
/**
  * Interleave two strings.
  * Assumes input parameters aren't null.
  */
def interleave(String a, String b) {
    int maxlength = [a.size(), b.size()].max()
    def sb = new StringBuffer()
    (0..<maxlength).each{
        if (it < a.size()) sb << a[it]
        if (it < b.size()) sb << b[it]
    }
    sb
}

println interleave('Hello', 'World!')
// => HWeolrllod!
//println interleave(null, 'World!')
// => NullPointerException (somewhere within the method call)

If we call it with valid parameters, everything is fine. If we call it with null we will receive a NullPointerException during the method's execution. This can sometimes be difficult to track down.

Applying this refactoring gives us the following code:

Code Block
package introduceAssertion

def interleave(String a, String b) {
    assert a != null, 'First parameter must not be null'
    assert b != null, 'Second parameter must not be null'
    int maxlength = [a.size(), b.size()].max()
    def sb = new StringBuffer()
    (0..<maxlength).each{
        if (it < a.size()) sb << a[it]
        if (it < b.size()) sb << b[it]
    }
    sb
}

println interleave('Hello', 'World!')
// => HWeolrllod!
//println interleave(null, 'World!')
// => AssertionError: First parameter must not be null.

This is better because we become aware of any problems straight away.