Over engineering – good sides of it
Abstract: How much can you over-engineer simple formula for converting units.
There was this holiday contest (in one of the programmers forums) based on the idea of writing over-engineered tool for converting miles per galon to liters per 100 kilometers. You can find plenty of solution for this one. You can find number of online converters. You can even type in
20 miles per gallon to liters per 100km
inside browser’s address bar and you will get
Still, it’s not the point there are tools performing conversion like this one. Question is. To what extent one can over engineer it? And by over engineering I don’t mean obfuscating. To be honest, I am little bit bored with codes that are ugly, use esoteric syntax and has names lasting half of the screen. I don’t think it’s funny anymore to produce things like
echo =1/*"beat that ;)" | tail -c13 #*/;main(){printf("beat that ;)\n");}
in order to make the whole picture blurry.
So, I have decided to take different approach. I have decided to pack as many different things into the solution as possible – of course time was a constraint here. In theory, you could have a solution based on building layer on top of the layer into infinity.
While piling up all these small things, I wanted to get most of it. I wanted to recall things I have learnt in the past, to learn new stuff, and play with the integration process. That’s what I eventually came up with.
Making things easy to run
One of my decisions was to make the tool as portable as possible (macOS/Linux). The obvious choice – Docker.
As you can see, Docker image is based on quite some number of external components.
State-of-the-art testing
I have decided to add state-of-the-art testing features into final tool. This is why you can find both: JUnit 5 and googletest inside final solution. I know that there are people who use pytest for testing C/C++ (btw, why people always say C/C++, isn’t that sort of saying something like Java/JavaScript – I know, I know, it’s a different thing, but still …)?
Anyway, I have decided to put all the fancy testing there, because it’s, fancy. However, there are people who think that putting testing (TDD) in front of everything is not quite a good idea – Erik Meijer – One Hacker Way Rational Alternative of Agile. However, I want to be in the line with all fancy stuff, thus, you can find all these unit tests there.
CLI based
CLI will strive to surpass all the other stuff. You can have fancy Cocoa based apps, you can have Windows 10, yet, eventually you will find CLI most useful one.
I know, I know. I over exaggerate. Of course there is no chance to go back in time to CLI based terminals (well, for MUDs, maybe). However, sometimes it’s really more convenient to build something for CLI comparing to GUI. Be honest, working on “Hello world” like app is way more easy in CLI. Anyways, this was my choice to go full CLI.
Final solution
You can find it here: converter-docker, and the execution is super simple
> git clone https://gitlab.com/mkowsiak/converter-docker.git > docker build -t converter \ --build-arg jdk_location=\ "https://download.java.net/java/GA/jdk11/13/GPL/openjdk-11.0.1_linux-x64_bin.tar.gz" \ . > docker run -i -t -e FROM=20 -e VALUE=25 converter
And that’s how it looks in the wild
Why over-engineering might be good
Working on over-engineered solution might bring a lot of benefits. First of all you can easily learn how various technologies meld. You can find all the spots where potential issues may arise, you can spot all the potential bottlenecks. These kinds of activities are way better than typical “Hello world!” applications because you have to cross the boundaries of various technologies. It’s way better approach comparing to multiple, isolated, “Hello world” like projects. And, while working on the over-engineered project you can let your imagination run wild. Sky is the limit :) And, it’s fun in a first place.
So, if you ask me whether it’s a good idea to implement crazy stuff from time to time, I’d definitely say it’s worth your free time :)