Skip to content

Public API

Richard Domander edited this page Mar 4, 2020 · 4 revisions

In general you want keep the number of public members in a class to a minimum. Public methods need to implemented and tested much more carefully than private ones, because you can't be certain how they will be called. Also, more code means more maintenance and bugs. Furthermore, unnecessarily exposing the inner workings of a class goes against the idea of encapsulation and separation of concerns. Before implementing a public method, it's worth checking if a method that fits your needs already exists in the ImageJ ecosystem.

Parameter validation and exceptions

However well you document your API, someone's going to call your public method with bad arguments. Thus it's necessary to check for null values and other invalid input, such as a negative length. Your documentation should mention these preconditions, and declare which exceptions will occur if they're not met. You should then also test that these exceptions really are thrown, when method is called with bad arguments. For example:

/**
 * Sets age.
 *
 * @param age a non-negative number.
 * @throws NullPointerException if argument is null.
 * @throws IllegalArgumentException  if argument is negative. 
 */
public void setAge(Integer age) throws NullPointerException, IllegalArgumentException  {
    if (age == null) {
        throw new NullPointerException();
    }
    if (age < 0) {
        throw new IllegalArgumentException("Age cannot be negative");
    }
    this.age = age;
}

and you would test this method:

@Test(expected = NullPointerException.class)
public void setAgeThrowsNPEIfArgumentNull() {
    final Person p = new Person();
    p.setAge(null);
}

@Test(expected = IllegalArgumentException.class)
public void setAgeThrowsIAEIfArgumentNegative() {
    final Person p = new Person();
    p.setAge(-1);
}

@Test
public void setAge() {
    final Person p = new Person();
    assertEquals(0, p.getAge());
    final Integer age = 25;

    p.setAge(age);

    assertEquals(age, person.getAge());
}

Public API and semantic versioning

The rules of semantic versioning relate to changes in the public API. A developer who depends on your code doesn't need to know if the internal implementation changes, but their code might break if you remove public methods, or change their signature.