Abstractly Abstracting Abstracts

There’s a problem that all devs fall into eventually. If you’re anything like me, you’ve probably done it a couple of times. Each time you promise you’ll never make the same mistake again, next time you’ll cut yourself off before you go too deep down the rabbit hole. And then you go and do it again. You try and make the perfect abstraction.

I’m only writing this because I’ve gone and done it again. It’s an inevitability, given the mentality of a geek. We like automating tasks so we don’t have to do them again. Like combining a few JS files into one. But then you realise you can concatenate more files. And why not throw in some minification while you’re at it. Heck, add some linting, versioning and mapping and you’ve made yet-another-build-tool.

And this is good. Writing code to solve a problem is easy. Well, not easy per se, but you know that each and every line is going towards solving the problem at hand. It’s when you accumulate code into modules, and modules into libraries and libraries into frameworks that you come to the question of how far abstracted you are.

I once tried to make a form submission handler that could accept pretty much anything. Form entries, CSV write-ins, even inbound SMS messages. I made that thing so composable and generic you could probably accept answers written in Klingon on a Bat’leth. And it worked.

Then I tried making a social media aggregator and found that providing access to content is a very different toolset to providing analytics of that content. But of course, it had all been abstracted away into this one perfect system which did neither task very well.

So now I try and walk the line. The code should do the task and nothing more. There are known unknowns, an aggregator may need to accept new sources, but there are also unknown unknowns, a source that may not subscribe to a normal pull model for instance.

Get it working. Get it working fast. Get it working well.