Kotlin code style


    For a year and a half of working with the Kotlin language, we transferred all our projects and frameworks to it. So that developers can quickly get involved in work on a project, and the review code does not turn into an endless debate, we decided to formalize the accumulated experience and developed our own code-style.


    Go!


    Each developer writes code based on their own experience and habits. If one developer or code is written for yourself on a project, this is not a problem. But in large teams working on several projects, problems inevitably arise:


    • code review takes a lot of time and nerves - without a single standard you can argue ad infinitum;
    • it takes much more time and effort to immerse a new person in the code;
    • it’s more difficult to concentrate on the function that the code performs;
    • as a result, the project looks like an imprint of all the specialists who took part in it.

    And even if now you are the only developer on the project, do not forget - someday it will end. And it depends only on you whether the new person in the team will be grateful to you or first of all will try to find out your address.


    Having a single style of writing code allows you to solve all these problems.


    Why now and why we


    Kotlin is quite popular in the community of Android-developer and every day gathers more and more supporters . But finding the style of writing code that you can follow is still a problem, and the agreements published on the official website of the language do not give comprehensive answers, since the number of rules that are present there can hardly cover most of the needs of the team. For example, they do not contain rules for formatting functions, their calls and descriptions.


    During the writing of the article, an official guide from Google came out with answers to questions about writing code on Kotlin, which to some extent influenced the article. It was interesting for us to compare the results and analyze what our opinions agreed on and what we did not agree with.


    About the rule development process


    The process of developing a unified style with which such a large team as ours would agree is not an easy one: to collect ideas and suggestions, take into account each person’s opinion, and recall what points cause controversy over the code review. It is expected that it will be almost impossible to achieve a single verdict on all issues, but it is important that everyone understands the importance and usefulness of the process, are ready to make concessions and comply with the decisions made.


    Of course, over time, the set of rules can be revised and supplemented - we plan to keep our set of agreements up to date.


    Controversial issues


    You can familiarize yourself with our idea of ​​how the code should look at the link at the end of the article, and below we would like to present particularly controversial and controversial points.


    1. View and Kotlin Android Extensions field names


    The rule

    Kotlin Android Extensions View fields use lower_snake_case naming style


    In developing the standard, we tried to abstract from external dependencies or the possibilities of using the IDE and focus on the language in its purest form. But still made an exception for Kotlin Android Extensions. Since most often we use Kotlin in Android development, and applications cannot do without using XML, since most resources are described in this format in the style of lower_snake_case. Thus, we made an exception for View identifiers (we describe them in exactly this style) and calls to these fields (although if you look at how this magic works in runtime, it turns out that these are not variables, but keys for obtaining values ​​from HashMap) . From the code it looks like an appeal to a field written in the style of lower_snake_case, but at the same time it is always visible in the code that a call is made to the View field.


    2. The order of private methods


    The rule

    Class structure:
    1) companion object
    2) Fields: abstract, override, public, internal, protected, private
    3) Initialization block: init, constructors
    4) Abstract methods
    5) Overridden methods of the parent class (preferably in the same order in which they are follow in the parent class)
    6) Implementation of the methods of interfaces (preferably in the same order as they follow in the description of the class, observing the order in which these methods are described in the interface itself)
    7) public methods
    8) internal methods
    9) protected methods
    10) private methods
    11) inner classes


    Another controversial issue was the location of private methods. There are two common options: write them immediately after the method where they were used, or in the class structure after all methods. We agreed on the second option. Since we consider a class as some interface, it is first of all interesting to know what it does - due to the fact that all private methods are located at the very end, you can quickly understand the responsibility of this class by its interface. In private methods, as a rule, concrete implementations are already contained, and we often turn to them only if we want to make changes. And in this case, the structure of any class will always remain consistent.


    3. Constants


    The rule

    Immutable fields in (Companion) Object and compile-time constants are named in the style of SCREAMING_SNAKE_CASE


    The question of naming constants entails another important issue: what is a constant in Kotlin now? The language provides a keyword to mean compile-time const constants, but compile-time constants can only be of primitive type and String. As constants, I would like to use other immutable variables located in the Object block - for such cases, we have expanded our understanding of constants when naming, including such immutable variables in their number. Interestingly, in this our opinion coincided with the position of Google.


    4. Package Names


    The rule

    Packages are named in the style of lower_snake_case


    In the process of work, we often had a problem with naming packages: different features may not be so obvious that when creating a new package for them, you need to use two or more words to accurately reflect the meaning. In the package naming rules for Java from Oracle, package names are suggested to be merged without separators, which in our projects could lead to the appearance of packages with difficult to read names. Therefore, we added the ability to separate packages with the underscore symbol. It is worth emphasizing that the use of such a style should be a forced exception rather than a rule, and this should be avoided as much as possible.


    5. Annotations


    Another point on which our vision differs from the common one was the use of single annotations: in some recommendations, it is possible to write several annotations without parameters on one line or even leave one annotation without parameters on one line with the described method / field. Such an approach, in our opinion, is of little use (save space), and the code becomes less consistent due to such exceptions, so we decided to leave a single rule for all annotations: always indicate them from a new line.


    6. Functions as expressions


    We also limited the possibility of using function expression - to describe a function as an expression is allowed only if it fits on one line (for this, by the way, we increased the maximum line length to 120 characters). If the expression does not fit on one line, it is likely that with further changes there may be a need to translate this function into the usual spelling, and such an expression will not be easier to read.


    What do we have


    In the end, I would like to indicate why even despite the fact that Google has released its style guide, we still publish our presentation. As mentioned above, a set of agreements from the developer of the language itself - JetBrains, because of its laconicism, hardly covers all the needs of the team, I really hope that the Kotlin development team will not remain on the sidelines and will further develop this list. On closer inspection, you notice that most of Google’s rules were copied or reformulated with their style guide in Java, but we tried to take into account the experience of other related programming languages, but to a greater extent we were guided by the use of different approaches to styles, and it was this approach that allowed we reveal some points (class structure, description, function calls, and other rules).


    What's next


    Even after the adoption of a single standard for writing code, problems can arise: someone may forget the rules, or worse, start sabotaging them. It is good if this code is rejected at the stage of code review, but the inspector may not notice these errors or even participate in subversive activities. Despite the youth of Kotlin, tools for static code analysis already exist for it, for which it is possible to describe all the rules and track any violation automatically, which is already on the way in our backlog. The service will help developers to be more disciplined and free Reviewer from the need to verify that the code conforms to the accepted standard, and then these tools will become assistants in maintaining cleanliness on the project.


    References:


    1. Redmadrobot Kotlin Style Guide
    2. Coding Conventions from the official site of Kotlin-a
    3. Style Guide in the repository of Dmitry Zhemerov
    4. Google Style Guide for Kotlin

    Also popular now: