Skip to content

Instantly share code, notes, and snippets.

Embed
What would you like to do?
Fluent APIs to prevent NullPointerException
public class Consumer implements UserAPIConsumer {
@Override
public void doit(UserAPI userAPI) {
userAPI.withCurrentOrNextPeriod(new BillingPeriodContext() {
@Override
public void executedIfPeriodExists(BillingPeriod period) {
System.out.println("yes: " + period);
}
@Override
public void executedOtherwise() {
System.out.println("no: no period available");
}
});
}
}
public interface UserAPI {
/**
* Invokes the corresponding method on the supplied context.
*/
void withCurrentOrNextPeriod(BillingPeriodContext context);
}
public interface BillingPeriodContext {
void executedIfPeriodExists(BillingPeriod period);
void executedOtherwise();
}
public class Consumer implements UserAPIConsumer {
@Override
public void doit(UserAPI userAPI) {
Nullable<BillingPeriod> periodRef = userAPI.getCurrentOrNextPeriod();
if (periodRef.hasValue()) {
System.out.println("Yay: " + periodRef.getValue());
}
}
}
public class BadConsumerStillPossible implements UserAPIConsumer {
@Override
public void doit(UserAPI userAPI) {
Nullable<BillingPeriod> periodRef = userAPI.getCurrentOrNextPeriod();
System.out.println("Hmm, still skipping null check: " + periodRef.getValue());
}
}
public interface Nullable<T> {
/**
* Returns true if it's safe to call {@link #getValue()}.
*/
boolean hasValue();
/**
* Throws a runtime exception if called when
* {@link #hasValue()} would return false.
*/
T getValue();
}
public interface UserAPI {
/**
* Returns the current or next billing period,
* if one's available.
*/
Nullable<BillingPeriod> getCurrentOrNextPeriod();
}
// same as original/first version
/**
* An API consumer may implement this to use the UserAPI.
*/
public interface UserAPIConsumer {
void doit(UserAPI userAPI);
}
public interface UserAPI {
/**
* Returns true if the user has a current or next
* billing period.
*/
boolean userHasCurrentOrNextBillingPeriod();
/**
* Returns the current or next billing period,
* if one's available.
*/
BillingPeriod getCurrentOrNextPeriod();
}
/**
* An API consumer may implement this to use the UserAPI.
*/
public interface UserAPIConsumer {
void doit(UserAPI userAPI);
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
You can’t perform that action at this time.