Balancing Freedom and Standards
_Do changes often largely affect code complexity? Do you often find yourself criticizing the structure of the development process, or the actual code and building blocks of the system? Is it easy for you to jump around between services? These questions, and more, have been bothering me lately after I read an amazing article on cognitive load by Artem Zakirullin.
Some subjects related to cognitive load include tactics for small to medium problems, where there is usually a consensus. Others relate more to the workspace and development procedures. However, the topics that are harder to measure and define are the strategic decisions we make, which also affect the cognitive load of future code changes. These kinds of problems are often in constant debate because every such decision involves standardizing how we develop.
Standardization
Standardization means to couple your implementation with a set of rules, which can be enforced automatically, or by a person (during code review for example). It involves establishing guidelines and practices that ensure consistency and reliability across projects. It can come in many forms, for example: coding standards, documentation formats, and testing procedures.
It can reduce the overhead of jumping between services, improve collaboration among team members, simplify maintenance, and reduce technical debts. All of that is because you can assume that certain conditions appear throughout the system, and are not specific to one place. So understanding or fixing something in one place would help you do that to every component in the system.
Freedom
Conversely, freedom in software engineering allows teams to innovate, experiment with new technologies, and adapt solutions to unique challenges without rigid constraints. Every engineer would develop without any prior guidelines or organizational rules to care about.
Challenges of Imbalance
Finding the right balance between these two aspects would push teams to deliver robust, scalable software while enabling creativity and agility in problem-solving. However, if things are not balanced, it can reduce the ability to deliver high-quality code and the time it takes to deliver.
For example, if you decide to use common libraries in all components. It would be harder to experiment with more modern ones, but it ensures that if a related tech debt appears, you fix it once. Also, when the team is more invested in a smaller amount of technology, it becomes more deeply experienced with it, but if the technology is not well suited to the problem, things can get ugly.
Excessive Standardization
Different pieces are indirectly coupled via the rules of the standard. Over-standardization usually means that there is too much coupling between components via the assumptions of the standard.
Changes are harder to make, or at least, without being exceptional and unexpected, it may result in a risk of becoming outdated and engineers may find odd detours to fit a solution in the standard.
Excessive Freedom
Inconsistencies in code quality and style can lead to increased technical debt and maintenance challenges, making it difficult to implement system-wide solutions.
Furthermore, these inconsistencies can create barriers to collaboration and knowledge sharing among team members, as different coding practices complicate understanding and modifying code written by others. The skill of individual developers has a greater effect on the overall quality and maintainability of the code, highlighting the importance of having proficient programmers.
It is also harder to apply development operations for legal compliance, security and quality as it may require different procedures for each component or technology.
Achieving Balance
To summarize, these are some guidelines I find important to achieve the balance...
- Define core standards: Establish foundational guidelines that ensure consistency and stability. Especially in places related to cross-components dependencies, like APIs, and infrastructure. Make sure it is clearly but precisely documented.
- Own it: Make sure there is a team or a person who is the gatekeeper for the standard and is responsible for making it better and more accessible for everyone.
- Allow for flexibility: Encourage teams to innovate and adapt approaches based on project-specific needs.
- Regular review and feedback: Continuously assess and update standards based on feedback and evolving industry trends. Ensure transparency and that the changes are well communicated.
- It is all about the team: Make sure the team agrees and understands the motivation about the standard, and provide necessary training and learning resources so engineers have a better understanding of the standard subjects.
Conclusion
The balance between standardization and freedom changes between teams and organizations and it is not black or white. Large organizations that want to increase collaboration and ensure quality may benefit from standards, while small products that might change direction many times need this kind of flexibility.
Achieving this balance is a continuous process that requires collaboration, adaptability, and a deep understanding of both the benefits and challenges.
PS
After writing this post I found a lot of similarities between reusability and standardization. Reusability is one way to make standards among many other ways. This is a kind of standard that directly affects the architecture and its building blocks, while other standards can be more vague. I wonder why this subject bothers me so much, but I am happy to explore more angles on it. See more in my other blog post on over-reusability