-
Notifications
You must be signed in to change notification settings - Fork 12
Public API
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.
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());
}
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.