title: What kinds of pre-conditions are sensible in Design by Contract?
body: <p>Let's assume we have a class <code>Student</code> with the following constructor:</p>
  
  <pre><code>/** Initializes a student instance.
   * @param matrNr    matriculation number (allowed range: 10000 to 99999)
   * @param firstName first name (at least 3 characters, no whitespace) 
   */
  public Student(int matrNr, String firstName) {
      if (matrNr &lt; 10000 || matrNr &gt; 99999 || !firstName.matches("[^\\s]{3,}"))
          throw new IllegalArgumentException("Pre-conditions not fulfilled");
      // we're safe at this point.
  }
  </code></pre>
  
  <p>Correct me if I'm wrong, but I think in this example, I followed the design by contract paradigm by simply specifiying the (rather static) constraints on the possible input values and raising a generic, unchecked exception if those are not fulfilled.</p>
  
  <p>Now, there is a backend class that manages a list of students, indexed by their matriculation number. It holds a <code>Map&lt;Integer, Student&gt;</code> to save this mapping and provides access to it through an <code>addStudent</code> method:</p>
  
  <pre><code>public void addStudent(Student student) {
      students.put(student.getMatrNr(), student);
  }
  </code></pre>
  
  <p>Now let's assume there is a constraint on this method like "<strong>a student with the same matriculation number must not already exist in the database</strong>".</p>
  
  <p>I see two options of how this could be realized:</p>
  
  <h3>Option A</h3>
  
  <p>Define a custom <code>UniquenessException</code> class that is raise by <code>addStudent</code> if a student with the same matr. number already exists. Calling code will then look something like this:</p>
  
  <pre><code>try {
      campus.addStudent(new Student(...));
  catch (UniquenessError) {
      printError("student already existing.");
  }
  </code></pre>
  
  <h3>Option B</h3>
  
  <p>State the requirement as a pre-condition and simply raise an <code>IAE</code> if it doesn't hold. Additionally, provide a method <code>canAddStudent(Student stud)</code> that checks in advance whether <code>addStudent</code> will fail. Calling code would then look something like this:</p>
  
  <pre><code>Student stud = new Student(...);
  if (campus.canAddStudent(stud))
      campus.addStudent(stud);
  else
      printError("student already existing.");
  </code></pre>
  
  <hr>
  
  <p>I feel that option A is much cleaner from a software-engineering point of view, for at least the following reason:</p>
  
  <ul>
  <li>It can easily be made thread-safe without modifying the calling code (Thanks to Voo for pointing me to <a href="http://en.wikipedia.org/wiki/TOCTTOU" rel="nofollow">TOCTTOU</a>, which seems to describe that exact issue)</li>
  </ul>
  
  <p>Thus I wonder:</p>
  
  <ol>
  <li>Is there a third option which is even better?</li>
  <li>Does option B have an advantage that I didn't think of?</li>
  <li>Would it actually be allowed from a design by contract point of view to use option B and define the uniqueness as a pre-condition of the <code>addStudent</code> method?</li>
  <li>Is there a rule of thumb when to define pre-conditions and simply raise <code>IAE</code> and when to use "proper" exceptions? I think <em>"make it a pre-condition unless it depends on the current state of the system"</em> could be such a rule. Is there a better?</li>
  </ol>
  
  <p><strong>UPDATE:</strong> It seems like there is another good option, which is to provide a <code>public boolean tryAddStudent(...)</code> method that doesn't throw an exception but instead signals error/failure using the return value.</p>