How to Get Buy-In for Cleaner and More Structured Code

clean codeengineeringproject-managementrefactoring

I am at my company for half a year now and think that I have gotten a fair idea of their codebase. Initially I didn't dare to form strong opinions, but now I start to feel that the code could benefit from a more structure and more software engineering.

My coworkers do a great job of adding new features, creating a cool product and so on. I just feel that there is no second refactoring and cleaning step, just the initial “making it work”. Given that we in the team are all scientists, and it is a growing company with a relatively new and rapidly evolving product, I can see that a flexible prototyping mindset was appropriate. At the university I have seen many projects start and eventually collapse into themselves as the grad student effectively was the project owner, they spend the time during their thesis on “making it work” and cut more and more corners until graduation. The next student would look at their code and usually throw it away. I don't want to see the company plateau in speed, so I believe that continuous refactoring needs to be part of the process.

I've just read “Clean Code” (R.C. Martin), and had years ago read “Code Complete” and “Rapid Development” (S. McConnell). In a small side project I have recently performed refactoring via abstraction. I added dependency inversion on an external library and then exchanged that for a different one. It didn't took long and the result feels amazing. Also I have tried to refactor everything I can and I could directly sense the increase in speed going forward. When I cook, I try to clean as I go to have countertops usable.

Some of my team members have a different perception on this, just like I did years ago. A decade ago I would laugh about Java, how people specified interface IWidget, class Widget and abstract class AbstractWidgetFactory and class FrobnicatingWidgetFactory when they could just have a class FrobnicatedWidget to start with. I thought that having less lines of code would be more readable in every case. But over the time I have changed a bit, I feel that if there are class TextLogger and class BinaryLogger there may is an unwritten structure with an interface Logger wanting to be made explicit. So in our code (which is Python and C++), I see abstractions and patterns which are implicitly present. And I would like to make them explicit.

The co-workers find that adding any encapsulation or standard design patterns to the code explicitly makes it more complicated. Adding another virtual class as the parent supposedly only adds a new class, even though the current classes already have an (implicit) interface. And I want to modularize classes further, they say that increasing the number of classes only increases the complexity. I say that a single class that does too many things is more complicated than the same logic in multiple decoupled classes. But I don't seem to get them to see the things like I do.

I am a scientist programmer myself. I have spent years writing code that works and just left it like that. Only over years of being annoyed with not understanding my own code I came to read about actual software engineering. I still don't dare to fully call myself “software engineer”, but I aspire to get there. And from the books I read I have the impression that I am on the right track. But of course I could be wrong.

I would really just force everyone to read “Clean Code” and to start think exactly like I do and do as I think would be correct. But of course it doesn't work like that. And it doesn't make sense either; my judgement isn't perfect, my experience limited and so on. Rather, I would like to have a professional discussion but would need to have more convincing arguments for the people who feel that refactoring would slow us down and would make the code more complex.

So my questions are:

  • Am I generally on the right track with my perception of conception and mid-term maintenance costs?
  • How can I get buy-in for and cleaner coding from coworkers who have a different perception of software development and mostly focus on getting things working?

Best Answer

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.