You can’t escape technical debt

Technical debt always comes back at you! (Image courtesy of Ambro at FreeDigitalPhotos.net)

It started like it always does: an innocent workaround to deal with a real problem that needs a prompt solution. It ended like it usually does: regretting the moment I let that happen in the first place.

We have this dependency to a third party module, which is closed-source. It turns out that it could provide some data in the wrong order once the app was restarted. No problem. We create an array of our own and we keep it ordered. It works and there is nothing obviously wrong with it.

Still, I could get a hint of the smell. I had to keep more state. I am very weary of keeping state. In this particular feature, I am leaning on the dependency to keep the state but, short of getting what we needed, I created the said array.

Shortly after, requirements change, because that is the way of requirements. They have a hard time staying still. They like to morph, usually expanding and expanding, adding more and more cases. What once was straightforward, started to have some new use cases, and suddenly a lot of special cases.

We need to roll and be agile and refactor as we go, but it looks like the deadline (outside pressure) is always more pressing than my principles of what code ought to be (inner pressure). At some point, I need my peace of mind, so let's roll. It works. What could be so wrong?

Then this crash happened. The stack trace in Xcode is useless, not showing any of our classes, so I conclude it must lie in the black-box dependency. Index out of bounds. Bunch of aficionados, ha! Who doesn't check for array bounds these days? I roll my eyes, write the email, and sit back, triumphant. It's somebody else's problem.

Um, they can't reproduce on their end. So let's add some try-catch to the fray, a bit all over the place to be honest, because I have no idea where this is crashing in a sea of delegate methods and asynchronous calls. This is iOS programming for real, boys and girls, not for the faint of heart!

Oh, my! It was the sorted array. When requirements changed, there was a new use case where we were not synchronizing our array, we get an inconsistency of state and surely enough… bum! There is our crash. Crazy little bastard.

This was the perfect lesson that technical debt always comes back to bite you. The innocent fix of today turning the time bomb of tomorrow.

I should have known better. In what hour of insanity I though it was a good idea to duplicate state between the dependency and our interactor? Yet I had to, that's how you roll in agile, right? You take some technical debt, write a TODO to come back to it, and put on your sunglasses to avoid being blinded by your own awesomeness, right? Right?

Well, as it turns out, not really.