https://blog.jooq.org/2016/02/11/dear-api-designer-are-you-sure-you-want-to-return-a-primitive/
Some APIs are set in stone. For instance, the JDK’s. Or public APIs, like the one between a database and a database client (e.g. JDBC).
Which means that being defensive when designing the API is a good choice.
One defensive API design strategy is to always work with parameter objects and return objects
When fetching data from a database, we get back a convenient API type, the JDBC
ResultSet
. Other languages than Java have similar types to model database results. While the ResultSet
mainly models a set of tuples, it also contains various additional useful features, like ResultSet.getMetaData()
or ResultSet.getWarnings()
, which are clever back-doors for passing arbitrary, additional information with the ResultSet
.
What’s best about these result types is that they can be extended backwards-compatibly.
Things look quite different when calling an update statement in the database:
1
| int count = stmt.executeUpdate(); |
Egh.
A
count
value. That’s it? What about any trigger-generated information? What about warnings (I know, they’re available from the statement. Which was modified by the call)?
Interestingly enough, this
count
value being an int
seems to have bothered some people long enough for the method to have been de-facto overloaded in JDBC 4.2:
1
| long count = stmt.executeLargeUpdate(); |
If performance doesn’t matter, always return a reference type!
This is really bad. The call runs over the wire against a database. It is inherently slow. We wouldn’t lose anything if we had an
UpdateResult
data type as a result of executeUpdate()
. A different example is String.indexOf(...)
which encodes “not found” as -1
for performance reasons.
when the first thing that comes to mind as being a useful method result is a primitive value (or worse: void).
https://blog.jooq.org/2014/05/16/java-8-friday-api-designers-be-careful/