Hi, Habr. My name is Evgeny Udodov, I am a co-founder and technical director of Roistat. I want to share our experience in developing a large and complex product - analytics systems.
TL; DR : We put
our Code Conventions on github and talked in the article about how to use it in practice.
When developing large products, there is a common problem - over time, a lot of legacy code accumulates, tasks become slower and slower. Also, as the team grows, developers start writing code in different ways and the lack of uniform rules can lead to conflicts and disputes.
')
Over the 4 years of our project’s existence, we have made more than 20,000 Pull Requests (hereinafter referred to as PR) and under the cat I will tell you how we solved these problems.

I tried to write the most useful article. It will be interesting to you if you are faced with the problems listed below.
If you are a technical director or technical director:
- You have to spend a lot of time to understand what is happening in the unfamiliar project code.
- For each task you have to point developers to the same errors.
- After discussing how to make a feature, the developer does not make the PR as agreed
- After a wrong PR, the developer, correcting some mistakes, makes others
- You spend a lot of time learning each new developer, even if he doesn’t stay long afterwards
- Senior developers come up with their own rules and impose them on less experienced guys.
If you are a product manager:
- When discussing each (seemingly not the most difficult) features, the developers tell you that it’s a long and expensive process.
- You roughly understand the principles of programming, but you don’t understand anything in the code of your project
- You have to wait a long time for new developers to get up to speed before they can perform complex tasks.
Start
At the beginning of 2014, only 2-3 developers worked at Roistat, but the first problems started already then. We are faced with the fact that every developer needs to explain the same mistakes. And with the growing number of developers, this situation has only worsened.
Also with experienced developers there was another difficulty. They each had their own accumulated experience and their own understanding of how to build the project architecture. Very often, their opinions contradicted each other.
Similar problems accumulated like a snowball. It was clear that if this continues, development will lose speed, flexibility, and each release will be given through pain.
Search solutions
First, we discussed the problem areas and agreed in words about how we would act in such cases in the future. Naturally, this did not work. After some time, everyone had a different idea of ​​what we agreed on earlier. Also about these agreements did not know the new developers.
Then we thought: "How to fix this information for all in the same form?". We tried to record instructional videos in which we talked about the architecture of the project and the basic principles of our development. But this format was very inconvenient. Video is difficult to correct or re-record. During the active growth of the project, new situations and new problems constantly arise, which require either new arrangements or changes to old ones.
Then we began to record the results of our discussions in a separate document. At the start it was just a few suggestions. But we agreed that developers should not impose their personal opinion on the code on the Code Review. Instead, they should refer to this document and indicate inconsistencies with it. If there is no necessary rule in it, then we must first discuss the problem, jointly work out a solution, write it into the document and then return and continue the Code Review.
And it worked. Problems with a different understanding of the agreements began to be reduced to a minimum. In the document we wrote detailed explanations with code examples so that no one could interpret them differently. Each new developer in our team could immediately understand what was required of him and how it is customary for us to act in different situations. Code Review instead of endless discussions and disputes turned into a fairly transparent and pragmatic process.
After half a year of work, this document already contained a lot of useful information and became an indispensable tool in the work of the team. We called it Code Conventions (or Code Conv for short).
Code Conventions
Code Conv - these are the rules that must be followed when writing code. We distinguish between Code Style and Code Conv. For us, Code Style is the look of the code. That is, the placement of indents, commas, brackets and other things. And Code Conv is the semantic content of the code. The correct action algorithms, the correct names of variables and methods, the correct composition of the code. Compliance with the Code Style is easily verified by automatics. But in most cases only a person can verify compliance with the Code Conv.
We take the following approach when using Code Conv.
For developer:
- The developer studies this document before writing the first line of code in our team.
- The developer must understand and understand the written rules. Just learn this document will not work.
- The developer strictly observes the rules of Code Conv when writing code.
- The developer creates a PR and immediately looks at it himself and checks for compliance with the Code Conv
- Developer submits PR to Code Review and corrects errors and inconsistencies of Code Conv, which are indicated to him and which he missed.
For Code Reviewer:
- The reviewer checks the code for compliance with the rules described in Code Conv
- If a comment appears to the developer during Code Review, then it should be accompanied by a link to Code Conv.
- If the Code Conv does not have the required item, then a working group is assembled that generates a new rule and fixes it in the document. After this, the reviewer returns to the PR check.
Few examples
In order to make it clearer what I am talking about, here are some examples of how this document looks in reality.
There is a table of contents at the beginning of the document. Over time, information becomes more and without a table of contents - nowhere.
We have 3 main sections: values, general principles and specific rules.
Values ​​are the business requirements of the development team. The business does not know the details of which methodologies and principles are used internally, but it is important for it that the product be developed simply, quickly and with time not be complicated. The whole team should follow these values ​​when working out new rules and for resolving issues that are not described in the rules.
Principles are ways to comply with the values ​​described earlier. They are a little more detailed, contain basic development methodologies and approaches that guide us. An experienced developer does not have to memorize the entire document. It is enough for him to understand these principles, and he can deduce all other rules from these principles himself at any moment.
But still, values ​​and principles can be interpreted in different ways. To avoid misunderstandings, there are specific rules and code examples in the document, showing how you can do it and how not to

There are a lot of such rules and they constitute the bulk of the document. Thanks to them, the order is respected.
In practice, the application of the document is as follows.
The developer making the Code Review leaves comments on code sections in which he noted non-compliance with Code Conv. In the commentary, he indicates which rule is violated. And optionally, if it is not obvious, adds an explanation why he thinks so.

For example, in this screenshot we see that the DRY principle has been violated (Don't Repeat Yourself). Despite the fact that in this particular PR the developer wrote the code without repetitions and it would seem that he used it only once, he still created such a method that cannot be used in the future without additional verification. That is, he created a method that obviously requires repetition of code and logic.
Frequent developer objections
Developers often try to push under different pretexts their code that does not comply with Code Conv. They find all sorts of excuses for their violations, but there are some of the most frequent.
"But once you can?"
Developers think that a one-time violation of Code Conv will not do any harm. They also sometimes believe that in some not very important place these rules do not carry value or are not critical. In response to this, we always refer to the
theory of broken windows : "If one glass is broken in a building and no one replaces it, then after a while there will not be a single whole window left in this building." If we make exceptions to the rules, then in six months we will find ourselves in a situation where the entire project code consists of such violations.
"But you need a very urgent!"
Developers often say that it will be a long time to do it normally, and the client is waiting for a solution to the problem and the edit should be posted as soon as possible. But, first, Code Conv does not prohibit anywhere to do the first iterations with a simplified code. Just this code should still meet the quality standards. Secondly, if you still need to break the Code Conv, then it is permissible to do this if the entropy created is not malignant (more on this below). But even in this case, everyone should have a common understanding that following the Code Conv in this situation will indeed be much more expensive.
A few words about entropy. Entropy is the amount of information that a project consists of (the information capacity of a project). If a developer writes code that adds critical information that every developer must know, then this entropy is malignant. Often this code is a time bomb. That is, at the moment this ignorance may not affect anything, and in the future, critical errors may be made because of it. This entropy we call malignant. If ignorance of information does not affect the work of other developers, then such entropy is not harmful, and we call it benign.
For example, if we are doing a separate microservice that will listen to some events and add statistics somewhere, then this service does not contribute to malignant entropy. If other developers do not know about this service, they will not make any mistakes, it will not affect their work. If it breaks, then no one will suffer except the owner of this service. So for such a service, it is permissible to do the first iteration (as Proof of Concept) with low quality code. And then, if it is necessary to develop it, then it will be necessary to correct the pledged technical debt and work with it according to all the rules. As a result, Code Conv does not prohibit experimenting and making quick and easy concepts, if it does not affect the rest of the system.
Conclusion
This approach has allowed us to maintain a high rate of development for more than four years, it is easy to introduce new developers into the work and not to slow down over time.
Of the minuses it can be noted that with this approach Code Review takes longer than usual. Even small tasks can be delayed for several days or longer due to not very critical errors.
But this minus is overlapped by pluses, since the malignant code does not get into the battle and all the “windows” remain intact.
We were repeatedly asked to share an example of Code Conv.
We decided to share with everyone and make it public. You can take it as is and use it right away. Or you can change for yourself. We are also open to PR and will review your suggestions for improvement.
Link to our Code ConvWe are actively expanding the development team, so if you are close to our approach, please respond to
our vacancy or write to the
mail .