I recently got a lot of ideas from the comments I got to a recent post on LinkedIN.
The purpose of Code Review is learning, not blaming.
But I won’t discuss code review nor pair programming today, they both deserve their own articles. Instead, I’d like to talk about the Coding Guidelines Document. Every mid-large team ends up writing such a document sooner or later. It’s a document written by developers for developers. It’s a rare kind of beast, as developers are notoriously reluctant to writing documents. Maybe they refrain from writing documents because they realized how fast documents get obsolete in our branch. This idea was captured in the Agile Manifesto, 2nd item: “We have come to value Working Software over Comprehensive Documentation”.
So you might hear them saying that:
The next minute you finish writing a document about code, that document is already obsolete and should immediately be regarded as an archeology product.
That might be the default for detailed code architecture documents and documentation, but having this attitude towards a coding guidelines document will immediately defeat its purpose. The coding guidelines are supposed to represent the target coding style of the team, which all developers in the group follow every time they write code.
Developers themselves put their best efforts into writing this document. It’s true, the act of writing a coding standards document is extremely gratifying: you get to talk about clean code, design principles, and common issues frequently discussed in code reviews. You might start extracting typical code samples from your codebase, have brainstorms and architecture meetings. Then, after a while, you complete that document, and you email it to everyone. Or even better, you put it somewhere visible, on a wiki, and invite people to help to refine it.
And there’s when it all stops.
Two years later, most people on the project aren’t even aware that such a document exists.
What went wrong? We involved everybody in writing that document; we broadcast it to everyone; perhaps we’re still linking it in any email we regularly send to the team members (like the timesheets reminder email 💡). We even took the time to keep that document in sync with the patterns commonly occurring in code reviews.
But somehow, everyone simply ignores it after a while.
What to do? You need a reset.
I want you to delete that document and then enjoy rewriting it together. A page with ten rules (💡) that everyone takes into account is far better than a state-of-the-art 50-pages Clean Code book chapter that no one cares about.
So every 6-12 months, delete it and start anew!
Tell everyone in the team to write down 5-10 things they would like to see in the Team Coding Guidelines Document and leave them several days to think over.
Every developer should compile her “personal wish-list of coding guidelines”, because every one of us struggles to master a different set of design goals as she progresses through her career. For sharpening your skills, it’s crucial to try to synthesize these goals in writing, put a name to the issues, and try to describe them in your own words. Plus, the simple fact of writing stuff down tends to make that stuff weigh more for oneself. So push hard: send reminders and insist that every single developer in the team squeezes these bullet points, no excuses.
You may even put together a little contest: vote for the best topics and offer prizes for the best items or variants. The goal of the Team Coding Guidelines is to find a reasonable common denominator, neither bloated with trivial rules, nor subjective, or too advanced as for a super-senior.
But again, delete it? Really?
The team coding habits may have changed since you wrote those guidelines. The very fact that you already had such a document shows a concern that likely helped your developers improve, so they don’t commit the same errors as they were one year ago. Perhaps you realize some rules became useless or evident to everyone. Or maybe you’ve concluded that a particular guideline doesn’t pay off in the long term (example: extract constants from every number in the code). Either way, a rewrite will demand that every rule in there to be strictly needed.
But more importantly, deleting and rewriting the document anew is so much fun; it’s a joint creative act. Plus, in the end, everyone will be among its authors and signers, and that will feel like a sort of Team Clean Code Manifesto. A joint, well-understood commitment tailored to your codebase and team skill level.
The Coding Guidelines Document is a Team Code Quality Manifesto.
You could cheat a bit and have a quick look at the old document before deleting it, but anything you propose to add to the new guidelines document should be needed today, and you must honestly convince the rest of your team about that. Then archive the old guidelines for historical purposes only.
Ok, now you’ve (re)written it. What next?
Adjust in Regular Team Design Meetings
Every month sit together with your team and have a chat about every point in this document. Go through all of it in an hour. If it takes longer than that, that’s a sign you should shrink the document or repeat the meeting more often. This meeting doesn’t just allow to continuously adapt and update the rules, but more importantly, offers an opportunity to discuss any tricky design topics.
The best code happens when you discuss its design with someone else.
The simple fact of articulating the design ideas and tradeoffs is crucial to produce simpler, cleaner, and more expressive code. At the same time, hearing your colleagues talk about design is extremely beneficial in terms of learning but also motivating you to do a better job. “If they are talking about it, then it’s important”. But try to make everyone contribute to the discussion if you get to facilitate this meeting.
Developers are famously reluctant to meetings. They rather spend weeks in code, suffer harsh code reviews, and play “I know better” than sit down in a meeting together. They might actually tell you that they “don’t have time for that”. But that’s crap! Weeks of rework can spend hours of design meetings – but make them understand it’s not their private time they spend there.
Time spent on a coding guidelines document is time earned.
Any time spent on constructively brainstorming and fine-tuning the guidelines to follow is by far more time- and stress-efficient than repeatedly arguing about recurring design flaws or painfully reworking the code you’ve put your best effort into writing. These meetings not only help with explaining those rules, but you might get to challenge some of the rules you don’t like.
On the other hand, you might find out that the vast majority of your colleagues are against one of your personal “best practices”. For example, they might not be so in love with the ternary operator (?:) as you are. Just saying 😉. This social pressure might convince even the most stubborn colleague to adjust his style. 💡
And slowly, throughout these meetings, your Coding Guidelines Documents will tend to grow indefinitely over years, becoming harder and harder to digest for anyone joining the team. But it’s exactly those new additions to the team that need this document more than any others, to either assimilate or challenge it. Throughout my career as a trainer and consultant, I’ve seen many projects having prohibitively long and complex coding standards documents that no one even dared to open.
You might try several ideas to shrink it back to a tolerable size:
- remove the obvious
- extract the complex
- use tools for formal rules
- cluster by topic.
The last idea simply means to split the document depending on the area they target: for example frontend code vs backend code. Even if there are similarities and you’ll repeat some rules, the coding style is usually substantially different as the challenges they face are different.
We’ll briefly cover the other techniques below.
Upvote the Rules you Discuss
As a team grows in skills, some items in the coding guidelines document become so obvious that they can be removed. How do you know which ones?
One trick is to have that guidelines document on a wiki and upvote the rules every time they are used/referred in a code review or pair programming discussion. In other words, if two people end up discussing that rule, it should get a
+1. You may even try to sort the topics based on those votes, to start with the “hottest” ones.
Then, in a Team Design Meeting look at those counters, and if a rule was never the subject of a debate between developers, consider removing it, if you all agree that it’s a trivial one.
Okay, but what if a junior developer joins the team and the trivial rules are gone? That’s why regularly deleting and rewriting the document is key. In addition, always consider Pair Programming with any junior developer joining the team for the first several weeks/months.
Note: If you’re Pair Programming/Mobbing all the time in your project, then celebrate! You are among the several 10-20% most lucky developers on the Planet!
Many teams working on complex legacy codebases end up writing elaborate tutorials and walkthroughs about how to redesign certain types of “typical mess” that occur frequently. Some examples I saw:
“How to replace ServiceLocator with Dependency Injection”
“How to move from programmatic to declarative transaction management” or
“How to replace side-effecting code with returning immutables”
Should these sections be part of the coding guidelines?
They would make the document hard to digest as each such tutorial needs intense focus to understand. It’s a different mind gear (slow thinking), so don’t mix them. Plus, if you delete and rewrite the document regularly to keep it alive, you wouldn’t want to lose them, right?
You will probably store them in an internal wiki page and link them from the guidelines document, but I would like to challenge you to do much more than that. If you are fond of those tutorials, then I would say you’re the perfect person to start a blog. So, to the extent possible, anonymize and upload those tutorials to a public blog for others to benefit too. If starting a blog is overkill, you can try a blogging platform like dzone.com or dev.to to get started. Just get it out there, share it with more people!
I think our profession is missing that: blogs, reports, and talks named “What have we done wrong: …….”, “The mistakes we did last year”. Very few developers are powerful enough to admit their/their team’s mistakes and speak openly about them. Have that courage, and let many others struggling with the same mistakes learn from you.
PS: if you already know of such a blog, please leave a comment with the link below.
Use Tools for Formal Rules
Don’t turn your Coding Guidelines Document into a list of numbers, use tools to check the static code analysis metrics like:
- length and max indentation of a function
- number of parameters
- max source code file size
- number of fields/class, etc
What’s that sound in your mind?
Yup, Sonar is there for you. Use it to your advantage: tailor those rules to match the beliefs of your team. Restrict those too weak (7 max params/function is the default?!), or relax those inapplicable to the current codebase (we have legacy 10K-lines files !!).
If you live in terrible code but you “want to do a good job from now on”, read about leak period: it allows measuring the quality only for the code that you changed since a given milestone, for example since the last release.
Install SonarLint plugin (available for both Eclipse and IntelliJ) and check the code every time before you commit. I’m not a big fan of having the analysis continuously running in my IDE, it distracts me. But I do love how IntelliJ allows you to run SonarLint analysis on the lines you changed before every commit (a nice checkbox in the commit dialog). No matter what, it’s far better to see the Sonar issues right in your IDE than on a webpage (aka The Hall of Shame), then ALT-TAB, search the file, line number, … edit.
Be sure to link the SonarLint plugin to your (paid) SonarCube/SonarCloud instance attached to your git repo to benefit from a lot more rules than those bundled with the free plugin. For example, this rule prevents turning your Spring components into stateless beans. Plus, you can then adjust the rules on your project profile and those rules will propagate into developers’ IDEs.
Free Tour for Newcomers
You should walk every developer joining the team through these guidelines, gently but firmly, a couple of rules every day (so you shouldn’t have dozens of them). Don’t rush, take your time to provide complex examples and detailed explanations, as well as exceptions to the rules and alternative solutions. Enjoy the moment as you, the mentor, are effectively teaching Clean Code, Simple Design, and/or Unit Testing, and explaining these concepts will enhance your skillset too.
Conclusion: What Should go in a Coding Guidelines Document?
I deliberately left this topic for the end, as I wanted to make it clear: the Coding Guidelines Document should be a LIVE document, expressing the beliefs and present goals of the team. A dead one is no use. And we’ve gone through several techniques to keep it alive. If you are using another trick that I didn’t mention, please let me know in the comments.
The topics it covers do indeed stem from the Clean Code, Object-Orientation, Functional Programming, Simple Design, and Unit Testing areas. But the exact content depends on the project/people mindset. However, as a conclusion, here is a summary of my preferences.
Coding Guidelines Document:
- Synthesize common code review discussions
- Focus on the pain points, avoid dull cargo-cult rules
- Don’t copy-paste rules from other projects
- Extract detailed tutorials into wikis/blogs
- Continuously massage the guidelines in Team Design Meetings
- Regularly delete-rewrite it to revive the commitment and keep it focused
- Treat it as a Manifesto for Good Code
- Use tools for simple metrics
- Gently walk every new developer through these guidelines
I’m curious what’s your take in the following scenario: we have multiple teams, contributing code on multiple projects, each with its own history, purpose and tech stack. Should each project have its own coding guideline? Should we group by “function” (e.g. frontend, backend, etc.)?
Even though it would be useful to share some coding guidelines in the “java” tribe, cross-teams, in my opinion such guidelines are not as applicable as rules established for a certain code base. Ideally, the tribes should share best practices internally, but then each team should tailor those ideas to the particularities of their codebase, and their preferences. For a deep legacy code, those rules will be closer to their reality, while on a more green project, they will tend to follow the latest trends of the tribe.
However, another challenge is egos, especially in top companies with great talents. But I dare to say that in a top product-company these guidelines are less? important than in a mainstream large one. What do you think?
Also a nice video about technical culture: The Spotify Engineering Culture – https://www.youtube.com/watch?v=Yvfz4HGtoPc&vl=en