This post contains what ideas / influences I recall when thinking about obviousness. Those thoughts are a bit discrete, not necessarily telling a coherent story.

Several years ago, I read a blog article by my favorite PHP programmer Tomáš Votruba - https://tomasvotruba.com . I can no longer find that specific article, but it explained Occam’s razor - “If there are two options, choose the less complicated one” - in the context of how code is read 10x more often than it is written. Thus, Tomáš argued, it really makes sense to optimize for reading. (It’s been years ago, sorry if my paraphrasing is incorrect - this is how it stuck with me).

This literally changed my life. Mostly how I write code, of course, but even the way I explain things (and that’s not only at work). I started being conscious about how my code will be read. What assumptions it will communicate.

How likely my code is to convey the same ideas that I had when writing it.

About a year ago, my then-colleague Rupert McKay was talking in a Twitter Spaces discussion about Software Craftmanship (episode no longer available). When asked what he considers to be quality code, he mentioned “having a good clarity of expression”. This felt like a great guiding principle, which I had been somewhat striving for but didn’t have if formulated so clearly. When now reflecting on what clarity of expression might mean to me, it would probably be “invoking the right assumptions, without focusing too much on implementation details”. Make your business logic really stand out, make it read like a story. This is what interfaces can really help with, and also what a lot of people using interfaces don’t use them for - tell the “what”, not the “how” (more on that in Matthias Noback’s great book). Of course interfaces are not the only way to do this, but they are a good entrypoint for someone not yet expert in object-oriented design (me included). (At this point I cannot help it but recommend a superb OOD book, I will most likely dedicate a separate post to it soon. Pardon the interruption.)

Some time ago, I was thinking about design patterns. What’s the deal with them? They do indeed provide a nice toolbelt of solutions for known problems, so that wheel does not need to be reinvented. But at the same time, they also do bring a certain set of assumptions with them. When used right, this can be immensely powerful. If the reader is familiar with the particular pattern, they are likely to have a similar set of assumptions around it, so you can easily convey the same ideas you had when writing it just by using the pattern, which is quite a low effort if done right. The “if done right” is of course the elephant in the room - most programmers are probably guilty with having applied a fancy new design pattern at a wrong problem when they learned about it and were not so advanced yet to “cool down” first. When your new shiny design pattern knowledge is your hammer, there are a lot of proverbial nails around. Sadly, such a usage still does convey the whole set of assumptions, but this time they are wrong for the problem and the reader can be greatly confused. “Was this just applied wrongly and I can now refactor it, or is it a Chesterton’s fence and I need to understand it better?” (This would also deserve a separate post).

The Occam’s razor principle could maybe save us from this. When there is a simpler way to convey the idea than using a design pattern, we should prefer that. And I suppose this will work out fine: the design pattern will only feel like the simplest way once we’re mastered enough to feel it’s really a good fit for the specific problem, thus we’ll only apply it where it really belongs. If it does not feel like the simplest way, it might be that we’re trying to force it where it doesn’t fit.