Lately I’ve been quite annoyed with the bugs that sneak into my object systems, especially UI classes. Test-driven development helps out a lot against this, although for some reasons (not the topic of this post) there are cases where I skip writing the tests. Yeah, I know, it’s bad. Most of the times this happens with front end code, and sometimes with Java backend code. I just hate Java, its verbosity, its exceptions, and occasionally I fool myself into believing I can skip the tests to leave Java world ASAP. I’m often proven wrong. I’ll work on that.
Anyway the weird thing is, when I do not write unit tests, I feel like my backend code is relatively more stable than my front end code. They both lack unit tests, so in theory they should be equally bad. So why does the backend code feel more stable, and is it actually more stable?
Well, it is. I have less bugs, and the ones I get are pretty trivial compared to the front end ones. So: why is my untested backend code “better” than my equally untested UI code?
Fact is, whenever I write backend code I tend to write it in a more functional style, regardless of the language I’m using. I’m writing a service after all, so the functional paradigm kind of pushes itself in, breaking the task down into functions, using hardly any additional object hierarchies, passing along whatever state I was dealing with, catching all the exceptions. Then, simply return a value. An inherently simpler design.
If I’m not modifying any object, I’m merely computing a new state. My function has no side effects, so all I really have to do is make sure it returns a correct value. With no side effects, my function is effectively decoupled from the rest of the system, and TDD becomes the most natural way to write code.
Hence I’m less likely to cause bugs. There you go.
This is kind of obvious once you think about it, but it’s not that apparent when you’re knee deep into designing objects. It isn’t for me at least.
So this is my quest now. Find ways to refactor object oriented systems (esp. UI) by extracting its “hidden” functional elements, whenever possible. I have some factual evidence to support this, but I need to develop a more systematic approach.