Non-Defensive

While being defensive for error scenarios can be a good practice, doing it by default without understanding the scenarios that could create an error tends to lead to lots of unneeded code. It is better practice to drive your design with tests, and allow that process to inform which scenarios to be defensive against.

Overly defensive example

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37

  class Greeting {

    public String formatGreeting(String name, Date dob) {

      if(name == null) {
        throw ArgumentException("Missing name");
      }

      if(dob == null) {
        throw ArgumentException("Date of birth missing");
      }

      return "Happy " + formatAge(dob) + " birthday " + formatName(name);
    }

    private String formatAge(dob) {

      if(dob == null) {
        throw ArgumentException("Date of birth missing");
      }

      /* .... format age ....*/
    }

    private String formatName(name) {
      if(name == null) {
        throw ArgumentException("Missing name");
      }

      if(name == "") {
          return "";
      }

      return String.Capitalise(name);
    }
  }

Less defensive example

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23

  class Greeting {

    public String formatGreeting(String name, Date dob) {
      if(dob == null) {
        throw ArgumentException("Date of birth missing");
      }

      return "Happy " + formatAge(dob) + " birthday " + formatName(name);
    }

    private String formatAge(dob) {
      /* .... format age ....*/
    }

    private String formatName(name) {
      if(name == "") {
          return "";
      }

      return String.Capitalise(name);
    }
  }