This is a very common conversation happening in most if not all dev teams. And in the end, it all boils down to this:
The coworkers find that adding these patterns to the code explicitly makes it more complicated.
What is very important to realize here is that both options are complicated, but for entirely different reasons.
To summarize the below explanation: when thinking in the scope of multiple projects (during your career/company’s lifetime/…), the effort needed to implement clean coding starts paying dividends. Bad practice coding comparatively trades those dividends away from a quick shortcut, and one that often ends up biting you in the end anyway.
Before I get into that explanation, answers to your direct questions:
Am I generally on the right track with my perception of conception and mid-term maintenance costs?
Yes. Bad practice means taking shortcuts, and shortcuts bite you in the end. For a proof of concept, bad practice is perfectly reasonable, because you have no expectation of long term reliability or maintainability. Once you’re entering the maintenance stage, all your bad practice shortcuts are going to catch up with you and bite you back severely.
How can I get buy-in for refactoring and clean coding from coworkers who have a different perception of software development?
I am a big fan of demonstrating issues, because if you can’t demonstrate the issues, then you can’t prove that there are any issues.
Bad practice manifests in several ways:
- Projects that never get done and never seem to reach a releaseable stage. Deadlines are forced to shift, and the “just a few more bugs to fix” stage never ends.
- Bugs that are hard to catch, hard to pin down, and require a long investigation and deep dive into the code
- Bugfixes often require substantial rewrites
- Fixing one thing somehow inexplicably breaks something else
- After investigating a bug, you need to find the specific person who wrote something to ask them about why it was written that way to make sure your change won’t break some side effect that you didn’t know about
- You’re always worried that any change you make is going to have unforeseen side effects
- “That’s just how it works. Don’t ask me”
- New (or changed) feature requests are met with resistance by the developers because of the amount of effort / rework that it would take
- There are “here be dragons” parts of the code that no one wants to go into anymore
- Meetings or discussions on specific issues seem to unavoidably end up needing to bring up some long-winded and ongoing problem/discussion and how the newly reported issue depends on that ongoing one and then the original discussion gets sidetracked by instead continuing the discussion on that ongoing problem.
These are just an aggregation of personal experiences. Probably not all of them apply to you.
Quite often, endemic bad practice (i.e. the workplace culture, not just one bad apple) manifests as problems being publically known/discussed/complained about, it’s usually not very hard to come up with concrete examples of how a specific project has been suffering under bad practice decisions.
However, from experience, don’t try to be the sole bringer of absolute truth. Because everyone who doesn’t already understand clean code is going to list every possible problem they can think of, and if you fail to perfectly answer all of them, that going to be taken as proof that your different way of working is just more troublesome.
Instead, refer to existing materials. Maybe try to suggest that only a handful of people (those who can sway opinion in the team) do some research and watch/read some resources on the topic. Maybe ask if you can apply this in a smaller project.
At a push, I’ve also refactored parts of the codebase in my own time, just so I could show concrete improvements to a team that kept blindly refuting that clean code is more maintainable. I actually implemented the last three bugfixes in half an hour (total) in front of their eyes, as opposed to the days of meetings/investigation it took them.
It all depends on how open your team is. Maybe they’re genuinely interested in improvement and you just have to show them a working example. It’s also possible that they’re going to outright refuse to innovate their coding “because that’s how we’ve always done it”.
This is one of the major struggles that clean coders deal with, and there is no clear cut solution to swaying other’s opinions, especially when you’re not in a leadership position.
Clean code is indeed quite verbose, and when you’re not used to that verbosity, it’s hard to wrap your head around. However, once you have experience with it, the verbosity actually helps keep complexity down.
By keeping the code denser, it’s easier to see all of the code in a single screen without needing to scroll or navigate between several files, but that starts working against you once you need to actually change that code, because it’s so very easy to get distracted or start mistakenly affecting other parts that you did not mean to touch.
Taking a real world example, we could argue the same about a storage facility. Your analogous coworkers would be arguing something along the lines of:
If we stack all the boxes on each other, then it’s easier to see at a glance what we have in storage, and we don’t need to walk as far.
These are all truths, but they are a biased perception. What this argument glosses over is how much effort it’s going to take when you need to get something out of the box at the bottom of the pile, and how much more likely it is to knock a stack of boxes over while you’re working in the warehouse.
If we compare the example of a bad practice codebase (dense code, few files), and a good practice codebase (verbose code, many files), and you’re a newcomer to both the project and clean coding in general, then you’re going to be meeting a learning curve in either case.
In a bad practice project, the learning curve is repetitive. If you go to work on another bad practice project, you then have to learn its pecularities from scratch, and it’s always going to be a learning curve.
Similarly, when you hire a new developer for the (first) project, no matter their skill level, they have to learn everything from scratch.
In a good practice project, the learning curve is possibly a bit steeper, but it doesn’t repeat. When you move on to another project using similar clean coding, you won’t struggle understanding the code structure, because you’re already familiar with it.
Similarly, when you hire a new developer for the (first) project, and they’re familiar with clean coding guidelines, it will take them significantly less time to get started. They’ll of course still have to familiarize themselves with the problem domain itself (which is a given), but not needing to learn the coding architecture is not only a lifted additional burden, a clean architecture can help speed up their ability to browse through the code and understand it.