Last active
August 26, 2015 19:58
-
-
Save nipafx/20d7e831bf3585c3aaca to your computer and use it in GitHub Desktop.
Null-free Extended Address
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
public class Address { | |
// look ma, no comments required | |
private final String addressLine; | |
private final String city; | |
private Optional<String> postcode; | |
// nobody has to look at these constructors to check which parameters are | |
// allowed to be null because of course none are! | |
public Address(String addressLine, String city, Optional<String> postcode) { | |
this.addressLine = requireNonNull(addressLine, | |
"The argument 'addressLine' must not be null."); | |
this.city = requireNonNull(city, | |
"The argument 'city' must not be null."); | |
this.postcode = requireNonNull(postcode, | |
"The argument 'postcode' must not be null."); | |
} | |
public Address(String addressLine, String city, String postcode) { | |
// use 'requireNonNull' inside Optional factory method | |
// if you prefer a verbose exception message; | |
// otherwise 'Optional.of(postcode)' suffices | |
this(addressLine, city, Optional.of( | |
requireNonNull(postcode, | |
"The argument 'postcode' must not be null."))); | |
} | |
public Address(String addressLine, String city) { | |
this(addressLine, city, Optional.empty()); | |
} | |
// now if some method needs to use the postcode, | |
// we can not overlook the fact that it is optional | |
public int comparePostcode(Address other) { | |
// without Optionals we might overlook that the postcode | |
// could be missing and do this: | |
// return this.postcode.compareTo(other.postcode); | |
if (this.postcode.isPresent() && other.postcode.isPresent()) | |
return this.postcode.get().compareTo(other.postcode.get()); | |
else if (this.postcode.isPresent()) | |
return 1; | |
else if (other.postcode.isPresent()) | |
return -1; | |
else | |
return 0; | |
} | |
// of course methods that might not have a result | |
// return 'Optional' instead of null | |
public static Optional<Address> findAddress(String userInput) { | |
// find the address, returning Optional.empty() if not found | |
} | |
// getters are straight forward and can be generated | |
public String getAddressLine() { | |
return addressLine; | |
} | |
public String getCity() { | |
return city; | |
} | |
// look how the field's type matches the getter's type; | |
// nice for bean-based code/tools | |
public Optional<String> getPostcode() { | |
return postcode; | |
} | |
// in case this 'Address' is mutable | |
// (which it probably shouldn't be but let's presume it is) | |
// you can decide whether you prefer a setter that takes an 'Optional', | |
// a pair of methods to set an existing and an empty postcode, or both | |
public void setPostcode(Optional<String> postcode) { | |
this.postcode = requireNonNull(postcode, | |
"The argument 'postcode' must not be null."); | |
} | |
public void setPostcode(String postcode) { | |
// again you might want to use 'requireNonNull' | |
// if you prefer a verbose exception message; | |
this.postcode = Optional.of( | |
requireNonNull(postcode, | |
"The argument 'postcode' must not be null.")); | |
} | |
public void setEmptyPostcode() { | |
this.postcode = Optional.empty(); | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment