Creating instructions to tell a computer to do certain things in a certain order is an exact science; you either get the instructions right (and the computer does what you want), or you get the instructions wrong (and the computer does what you told it to). There is no third way (cosmic radiation shifting bits notwithstanding).
Software Development, that is, the act of creating software to fulfill a human need, is not an exact science. It’s not even a reproducible art (yet). If it were, we wouldn’t have so many failed projects in Waterfall, Agile, Monoliths, Microservices, TDD, Unit Testing, BDD, RAD, JAD, SDLC, ITIL, CMMI, Six Sigma, or any other methodology that attempts to solve human problems. If we could make it into a reproducible art, we would have already done so.
So why do we the act of creating software as if it’s a science? As if there is a One True Way? We know there isn’t, since projects of all stripes succeed (and fail); and we know that as of yet, there is no one approach for success (though there are many approaches for failure).
We even do this in objectively silly things: Tabs vs. Spaces, CamelCase vs unix_case (or is it unix-case?), ORM vs No ORM, REST vs. HATEOS vs. RPC over HTTP, or anything else. We do it in the form of “Style Guides” that detail exactly how the project should be laid out; as if the mere act of writing down our rules would bring us closer to successfully creating software. We make rules that apply to all situations and then castigate other developers for breaking those rules. Those rules bring us safety and comfort, even if they don’t make delivering software a success (or a priority).
Those rules we cling to for safety cripple us from making the best decision using the best information we have.
Style Guides are beautiful things; and I believe in their efficacy. By standardizing code, it becomes easier to change the code. There’s no cognitive load spent on the parts of the code that stick out; and that savings can be spent on fixing the actual problem at hand. But Style guides can go too far. Think for a moment about your database names and class names for Data Access Objects (DAOs). If you work in C#, they’re typically PascalCase. For instance, in SQL Server, Table names can be PascalCase with no issues (and they generally are). But if you do that in Postgres, your C# will look horrible:
private readonly string getByMyName = "SELECT * FROM \"my\".\"mytable\" WHERE \"myId\" = @MyId AND \"MyName\" IS NOT null";
In this case, your style guide brought you consistency across databases at the expense of developer health.
But we tend to take a good practice and morph it into a bad one due to misuse. You wouldn’t believe how many times I’ve run into an issue where I or someone else placed too much trust into an ORM, and next thing you know we’re outside in our underpants collecting rain water with ponchos to survive. Invariably the rule is put into place “No ORMs” or “Stored Procedures Only”, or some other silly rule that’s just there because the development team was pwned by a SQL Injection Attack due to misuse of an ORM, or N+1, or something
NO ORMs. Seems silly, right? I’ve personally witnessed it; Hell, I’ve made the rule myself. And I’ve done it for the best of reasons too:
- Let’s not complicate our code until we understand what we’re actually building. ORMs send us down a particular path, we don’t understand enough to know if that’s the path we want to be down
- Traditionally, ORMs handle one-to-many relationships very poorly; I’m OK with ORMs for very basic needs; but it’s that other 20% they’re terrible for.
- Why should I ask people to learn an ORM’s syntax when SQL does quite nicely?
And I was wrong. My reasoning was sound (at least in context of the information I had at the time), but it was wrong. What I should have said was this:
You want to use an ORM? Great, go at it. If and when it doesn’t meet our needs, we’ll revisit the decision; until then, just make sure you use a well-supported one.
And that would have been that. But I fell into the trap of thinking I was smarter than the person doing the work; to think that I was somehow saving them from making the same mistakes I did.
There’s really only one constant I’ve learned in creating software that succeeded, and software that failed: There is no one “True Way”. There is no style guide that will save us, no magic methodology that will somehow make your organization ship software. There’s only the day in and day out grit of your team, only their compassion for their user and each other, and their drive to ensure the software gets made. There are wonderful tools to help your team along that journey; but they are neither one-size-fits-all or magical.
They’re just tools, and they’ll work as often as they won’t. The deciding factor in what works is you and your team. Your team has to believe in the tools, the product, and in each other. If they don’t, it doesn’t matter what methodology you throw in front of them, it won’t help you ship software. So the next time you (or anyone) is making rules for your team to follow, ask yourself: “Do these rules help us ship better software?” If they don’t, fight them. There’s too much to do to embrace bad rules.