Below is a piece of Java code I wrote the other day. We’re not going to look into it too closely (and in fact, this post isn’t really even about Java per se), so here are the key take-aways:
- It’s for converting a
Tableof data (essentially, columns and rows, where each column has a name) into a
Placesobject, which is a proper Java bean, consisting of a collection of
Placehas a name, some boolean fields and some numeric fields.
- There’s lots of Java Streams work going on here, and heavy indenting.
- This code isn’t really heavy-duty, it’s pretty thrown-together. The exception handling is dreadful.
- It’s fairly hard to read
The whole purpose of this function is really to establish a mapping: essentially, it is saying that some
Tables map to
Places, and here’s how you do it. It looks like this:
– all tables, place tables -> Place objects.
But in order to construct the mapping from
Places, we also need to create the mapping from
Table rows to
Place objects, the
Table columns to
Place fields, and the
Table cells to
Let’s look at where that happens:
So here I’ve highlighted where we establish these mappings:
- Column Name and
- Text Value of a cell, and the field value. (Mauve)
Ok, so this code kind of works and it looks terrible. But there are really big problems here:
- First, I can only convert from
Place, not back again.
- Second, I can’t tell ahead-of-time whether a
Tablewill convert to
Places. A table row could contain things that aren’t
Places, and then it would fall over.
- Third, given a
Places, there’s no way I can tell whether they are the same, without first converting one into the other, and then comparing them. That is, if I have an
equals()method defined for
Table, then I can’t make use of that to compare
Placeswith each other, even though realistically, if they are equivalent, then the equals should be equivalent… and the same goes for any other functionality I might declare on
Tableindividually. If they are equivalent representations of the same data, then the same operations should work on each of them, right?
So, to summarise:
- I want a way to declare an equivalence (i.e. a two-way mapping) in Java, rather than just a one-way mapping.
- I want it to not be a cause of eye-strain for the next person trying to read my code.
Scale Of The Problem
I am currently working on a project containing about 85 classes. Let’s break down what they’re used for:
|Some Kind Of Converter||25|
.. plus a few sundry others.
Also, I’m making use of things like Jackson for turning JSON into Java Objects. And a lot of Java’s standard library itself is for converting external forms to Java objects and back. Things like the XML Libraries for turning XML into Java objects, REST Libraries, for turning HTTP Requests into Java Objects and JDBC and ORM Libraries, for turning relational data into Java Objects.
In actual fact, one of the main reasons for using Java at all is because it has such a rich set of connectors: whatever the format, you’re almost certain to find that someone has written some kind of converter for it in Java. You don’t choose Java because it’s the easiest language to learn, you choose it because of it’s Ecosystem.
So actually, I think converting between one format and another is actually the lion’s share of all the code we write, especially if we are bolting together lots of open-source libraries to construct our software.
Add Your Star On GitHub to receive an invite to the GitHub Risk-First team.