Sometimes the best code is also the most boring.
Brendan Grove, a CTO at payout company Prizeout, said that clean code should read like a textbook to future contributors.
“They should know what page to turn to for the information they need, and they shouldn't be forced to read the whole thing to understand various modules,” Grove said.
And while most tech companies wait until code reviews to clean up bugs, dedicated engineers are implementing techniques to ensure code cleaning begins at inception.
Self-documenting, eliminating modular block redundancies and type checker tools all help ensure that when the code is ready for a review, engineers can utilize that time to minimize technical debt, track improvements and enhance the code.
Software Engineer Robin Bonatesta said consistent naming conventions, documenting code purpose, creating reusable modular code and writing thoughtful commit messages help her team at digital media company theSkimm develop clean code. From there, peer programming and code review should be performed diligently.
When it comes to writing clean code, what are some best practices you follow, and why?
Clean code is well organized and easy to read, which is especially important when working on a team. When programming, I try to evaluate if my code will be easy to understand for my teammates as well as my future self. Some ways I achieve this include using clear, descriptive and consistent naming conventions, documenting the purpose of code when the underlying decisions may not seem obvious and creating modular code that can be easily reused. As a final effort, I prioritize writing thoughtful commit messages that describe the changes I make to keep a written record in our version history.
I try to evaluate if my code will be easy to understand for my teammates as well as my future self.”
On the flip side, what are some bad coding habits that you wish every developer would stop doing, and why?
As engineers, sometimes we tend to overcomplicate implementations with unnecessary design patterns or libraries, which can impede readability and flexibility. Additionally, when pull requests and commits are really large, peer reviewing that code becomes more daunting, resulting in less thorough feedback. Lastly, failing to document code and track technical debt can create a codebase that is harder to maintain. Keeping maintainability in mind and getting feedback early and often can help prevent these habits.
How does your team make clean code a priority? What are the benefits of this approach to software development?
At theSkimm, we use code reviews and pair programming as a way to ensure readability and shared knowledge among team members. When possible, code is reviewed by multiple teammates and pull requests are not merged until code has been approved. Pair programming is helpful on large implementations or when making important design decisions at a low level.
As a team, we share a responsibility of tracking needed improvements and technical debt, and we prioritize a percentage of the work in each sprint to continue to enhance our code over time. We believe it’s important to carve out time in our product development process to make these improvements an ongoing habit.
Tory Mance, a software engineer at healthtech company CredSimple, said streamlining code blocks to prevent redundancy helps reduce bugs. Organizing code by following patterns allows others to hop in when updating or utilizing. Mance said open communication is essential for all of this to happen.
When it comes to writing clean code, what are some best practices you follow, and why?
Don’t repeat yourself. Having multiple methods or other blocks of code that serve the same purpose can cause problems when trying to debug an issue. This can lead to a bug being fixed in one place and not another. It also can lead to redundant tests. Keeping things consolidated when possible keeps things easier to read, reduces the amount of code and ends up saving you from doing extra work.
Follow patterns. Whether it’s naming, style or architecture, having distinct patterns in your code makes it easier for others to pick up work that involves updating or utilizing it.
On the flip side, what are some bad coding habits that you wish every developer would stop doing, and why?
Overreliance on third-party libraries. There are a lot of great libraries out there, but I think a common pitfall many developers fall into is relying too much on third-party code to get the job done. There are obviously exceptions, but in my experience, there usually comes a point where you need a library to do something specific to your domain that it just wasn't built to do. At that point, you’ve already invested a ton of time into supporting this library and now need to find a workaround. Not only that, but the more you rely on third-party code, the more bloated your codebase becomes with extra dependencies.
My rule of thumb for using a library is that it should solve a clear, concise problem and it needs to have a good amount of support from its creators.
We encourage feedback and empower employees to have open lines of communication when collaborating to ensure we are functioning effectively as a team.”
How does your team make clean code a priority? What are the benefits of this approach to software development?
I think the biggest way we make clean code a priority is through open communication. This creates more opportunities for pair programming because such a culture allows developers to feel more empowered to ask for help. Similarly, if a code review brings up larger questions, we encourage setting up a group discussion to ensure a solution is agreed upon. We really value honest and transparent communication. We encourage feedback and empower employees to have open lines of communication when collaborating to ensure we are functioning effectively as a team.
Gang Luo, a senior software engineer at fintech software company Addepar, values the power of comments in code. Comments should motivate, provide concrete examples and reference external resources for utter clarity. Concise code comments help make the review process more human-friendly.
When it comes to writing clean code, what are some best practices you follow, and why?
First, specific and meaningful naming is important. It provides a level of abstraction, hides implementation and calculation details behind variables and functions, and allows quicker and more precise comprehension of the code structure without unpacking every single "black box" and diving into details unnecessarily.
Having a dedicated class to represent and refer to all variables with meaningful names is a great way to solve that. What's more, an explicit "profile" provides a high-level overview. Is your class supposed to be singleton? Are you ready for someone else to extend your class? Is your implementation thread safe? Is it immutable? Those are important characteristics for people to understand the code briefly but precisely, and to use it properly. Be mindful of them and explicitly annotate and document them.
Finally, don’t overlook the power of comments. Don't simply rephrase code behaviors in human and natural language, but write comments that expand the context with motivation, concrete examples and references to external resources. Such extra level of detail and verbosity compensates for code that goes the opposite direction and is a critical part to promote friendliness to humans.
...Don’t overlook the power of comments.”
On the flip side, what are some bad coding habits that you wish every developer would stop doing, and why?
One common problem is to speculate the usage pattern and overengineer. More often libraries are conceived with some clear usage patterns, particularly in a smaller and cross-functional environment. Still, people feel they have to go beyond and implement everything just to make the code look "complete," even if they are not immediately useful. Or in cases where an IO component could be a bottleneck in the future but isn’t yet, it is not surprising to see some premature optimization being applied early just to make the code "scalable" or future-proof.
As much as those concepts (versatility, scalability) sound appealing, it creates problems. First, it is simply a waste of time worrying about the problems at the wrong time and wrong places. It also creates long-lasting debt to maintain the code and tests. Additionally, it makes the code more complicated with no immediate benefits. In the end, it is unlikely the implementation and optimization made today will be the right fit for the feature or performance required tomorrow.
How does your team make clean code a priority? What are the benefits of this approach to software development?
Engineering teams across Addepar take code review seriously. Reviewers not only provide an extra safeguard for code quality, but they are keen to learn more details behind the code change. It is not uncommon to see reviewers catching up with context, motivation and restriction as much as they are making critical feedback. Such cross-pollination is a great motivation and comes back to push the author to pay extra attention to code readability, clean it up and structure it right.
In addition to human power, we also deployed automated tooling to cover common and repetitive issues, from an IDE profile enforcing code style to pre- and post-commit checks with static code analysis tools. The two combined not only maintain a high bar for code quality but are great ways for every developer to learn from peers and real world practices. They also make the software development life cycle a more rewarding experience.
To write clean code at payout company Prizeout, CTO Brendan Grove said his team focuses heavily on collaboration. Whenever an engineer writes code, they consider the fact that another developer will be expected to work with it as well. Joint tech planning sessions allow teams to review outline and pull requests as well as expectations of themselves and each other.
When it comes to writing clean code, what are some best practices you follow, and why?
I believe understanding the problem space is a necessary foundation for writing clean code. I like to think about solving a complex engineering problem as exploring a dark room; you need to take the time to explore the nooks and crannies, really understand the shape of the room and constantly rethink what you thought you had learned before.
This type of learning and iteration allows you to define the responsibilities of various services and develop the structure of your program. From there, clean code is really about standardizing and replicating patterns that can be defined by the team and can be unique to any given company. Similar APIs should follow similar structures, database naming conventions should track across services and complex logic should be well commented for future developers. The challenge is balancing perfection with speed, especially for a startup.
Ultimately, I believe clean code is all about picking the right structure for the problem, finding the right home for all the logic and allowing future contributors to read your service like a textbook. They should know what page to turn to for the information they need, and they shouldn't be forced to read the whole thing to understand various modules.
Clean code is all about picking the right structure for the problem, finding the right home for all the logic and allowing future contributors to read your service like a textbook.”
On the flip side, what are some bad coding habits that you wish every developer would stop doing, and why?
I think the biggest bad habit is starting with a structure that doesn't quite work, learning more and then continuing down the same path. Usually I see that this ends with unnecessarily complex functions, hard-to-understand code and, ultimately, code that is prone to bugs. Code that feels too complicated probably is.
Two big pet peeves of mine are when logic seems to live across multiple services with no clear ownership between them and over-optimizations in the name of efficiency. Both make it hard to build on top of the foundation, with new features forcing changes in multiple places or the seemingly "efficient" code being hard to understand. Institutional knowledge then becomes a bit too relied upon. There is nothing wrong with a simple IF statement if it's clean, readable and gets the job done.
How does your team make clean code a priority? What are the benefits of this approach to software development?
Our team has a heavy focus on collaboration. We try to bring in teammates with various backgrounds and expertise, which allows everyone to learn from each other. It also ensures teamwork and that team members can contribute to the growth of others. I think this creates a feeling of responsibility to each other that encourages clean code.
If an engineer knows their teammate is going to have to work in the same codebase in the future, they will want to give them a foundation of readable and understandable code with which to start. That is what they will expect of others when they dive into a new codebase that they have never worked on before.
We also have joint tech planning sessions and team reviews of both tech plans and pull requests. We try to outline and document expectations ahead of time for what we expect from ourselves and each other. I really love this approach with a focus on collaboration and ownership because I think we have cultivated a team that loves working both together and for each other. At the end of the day, that's really why you want to write clean code.
Aron Szanto, an NLP team lead at Kensho, a company that leverages data to develop AI, said they try to avoid artificial coupling of components. Artificial coupling can be avoided by being thoughtful and asking where a method, variable or class should reside, what parameters it should take and where it will be called. As well, using tools like Mypy and Black before review helps minimize errors.
When it comes to writing clean code, what are some best practices you follow, and why?
We insist on designing deep interfaces. Modules and classes should have few public methods, functions should have few arguments and provide sensible defaults, return types should be simple, and methods should do one and only one thing. This allows each capsule of code, big or small, to serve exactly its intended purpose while providing flexibility to extend or modify internal implementations transparently and at the proper level of abstraction.
One sign that a module's interfaces are too shallow is that its callers need to invoke multiple functions with many arguments to do conceptually simple things. Writing deep interfaces is the very best gift you can give your team and your future self.
Writing deep interfaces is the very best gift you can give your team and your future self.”
On the flip side, what are some bad coding habits that you wish every developer would stop doing, and why?
One anti-pattern we come across is artificial coupling of components. Coupling in software systems is a measure of the dependency between two modules. Artificial coupling occurs when functionally distinct structures are combined in code without a good reason.
Luckily, most forms of artificial coupling are easily avoided by asking “what does this thing I'm building actually need to know about?” when thinking where a method, variable or class should reside, what parameters it should take and where it will be called. A decoupled codebase is a happy codebase!
How does your team make clean code a priority? What are the benefits of this approach to software development?
Our team’s mantra with respect to low-level aspects of code quality is “don’t leave it to humans.” We use great tools like Mypy, Black, isort and Pytest to format, typecheck and test our code, before it's even proposable for review. These automated tools catch errors that even the most experienced engineers might miss. It also supercharges the effectiveness of code reviews when no one has to think about style, formatting, type correctness or other minutiae, instead letting themselves focus on the big picture.
At a higher level, we take care to manage and document the technical debt we accrue and be deliberate about whether its ROI, taking into account the cost of paying it off later, is still positive. We maintain a high code cleanliness bar, even when doing it right takes longer than doing it fast.
Last, we recognize that technical debt compounds when unaddressed, so we allocate strategic work time every month to allow ourselves to stop making immediate progress and instead return to areas where we made tactical tradeoffs in favor of expedience.
CTO Tim Julien said that location data company Radar’s clean coding best practices — like code reviews, writing tests and automated tools — are enforced in configuration to ensure engineers always follow them. Staff Software Engineer Craig Kochis and Senior Software Engineer Jeff Kao explained that tools can help keep the codebase clean and consistent but developers must still be thoughtful in their approach.
When it comes to writing clean code, what are some of the best practices you follow, and why?
“Whether it’s in the form of a linter like ESLint or static analysis tools like SonarQube that can catch bugs and security vulnerabilities, automated tools like these let developers spend less time thinking about how they should be writing code and more time solving the problems at hand,” Staff Software Engineer Craig Kochis said.
“On the front end, we leverage prototyping tools like Storybook to build our UI components in isolation before integrating them with the rest of the site. This lets us get quicker feedback on new designs and forces us to think about building components that are reusable in different settings. And as an added benefit, we have a growing library of usable and well-documented components that other developers can leverage in the features they build.
“I think it makes engineers understand the bigger picture of what they’re working on and why they’re doing it. Then, they usually have more empathy for the people who will actually use the product. So, they’re not just writing something and handing it off to someone else; they actually have to go through the steps of using it by going through the pain points themselves. And at the end of the day, that helps engineers build better products.”
...The code that you write at a company is not limited to just yourself; a lot of it is an exercise in communication.”
On the flip side, what are some bad coding habits that you wish every developer would stop doing, and why?
“Generally speaking, the code that you write at a company is not limited to just yourself; a lot of it is an exercise in communication,” Senior Software Engineer Jeff Kao said. “You can easily write code in a ‘smart’ way versus a way that everyone can understand. You could write something ‘smart’ all in one line, but that can lead to mental overhead or cost for the team because they won’t be able to understand or work with it. That’s why it’s important to have empathy for your teammates when writing code.”
How does your team make clean code a priority? What are the benefits of this approach to software development?
“We’ve configured Github such that you can’t push directly to master; you have to open a pull request,” CTO Tim Julien said. “Similarly, for security scans with SonarQube or functional tests, you won’t be able to merge to master until those checks pass. It’s freeing because you don’t have to remember to do it because the system just puts up those guardrails.
“To ship a feature to a customer, you’ll probably need to touch all of these. You don’t need to be an expert in every codebase but I do think that getting exposed to many languages helps you pattern match and pick up the idiomatic style of that language. For people who speak multiple languages, they talk about how each incremental language is easier to grasp because you get better at learning each time around. I think programming languages are similar.”