# Software Design/Code organization conventions

This page lists possible code organization (complexity, arrangement, structure) conventions that may be established in a codebase.
The goal of this page is to list all conceivable code organization conventions and rules regardless of their perceived importance and whether or not it's practical to enforce them in projects. See Conventions category for further information.

## Possible conventions
### Prohibited language constructs

Whether there are constructs and features of the programming language that must not be used in the codebase. Examples of such constructs and features that may be considered inherently error-prone and/or difficult for understanding:
* Ternary operators (condition ? optionA : optionB). Optionally, they may be prohibited only if are non-trivial (that is, optionA and optionB are not plain references to variables but some more complex expressions), or need to span multiple lines. Also, only nested (multi-level) ternary expressions may be prohibited (condition ? optionA : condition2 ? optionB : optionC). It is possible to prohibit ternary operators using automatic tools:
** Checkstyle's AvoidInlineConditionals pattern (Java)
* Assignments within expressions, or within if conditions in particular. The fragility of such code started the practice of Yoda conditions. Atomatic checks:
** Checkstyle's InnerAssignment pattern (Java)
** Compiler Warning C4706 (assignment within conditional expression) in Visual Studio (C++)
* do/while loops
* goto operators
* Exceptions
* Multiple (data) inheritance
* Extension functions
* Custom operators, operator overloading
* switch statements
* Implicit type conversion

### Limits on code complexity and size metrics

* Number of elementary components in boolean expressions. For example, an expression like (a && b) || (c && d) || e (5 elementary components) could be considered too complex and require to extract some part of it into an explaining variable. Implementations of functions like equals may be exempted from this convention: they may include boolean expressions with many components like fieldA.equals(other.fieldA) && fieldB.equals(other.fieldB) ... && fieldZ.equals(other.fieldZ).
* Level of parentheses nesting in boolean expressions
* Level of nesting of ternary expressions (if nested ternary expressions are not prohibited at all: see Prohibited language constructs section above)
* Number of parameters to a function
* Number of lines of code in a function
* Cyclomatic complexity of a function. Developers are not expected to estimate the cyclomatic complexity of functions manually, so unlike most other conventions this one can't be a verbal convention which developers follow casually. This convention must be enforced using automatic tools:
** ESLint's complexity rule (JavaScript)
** Checkstyle's CyclomaticComplexity pattern (Java)
** Cyclomatic complexity plugin for ReSharper for Visual Studio (C#, C++, JavaScript, TypeScript, Visual Basic)
** Radon's Cyclomatic Complexity metric (Python)
* Level of block nesting (decision nesting)
* Function fan-out: how many different functions are called from a function (including itself, if the function is recursive)
* Number of different classes referenced from a function. In Java, this convention may be enforced with "Overly coupled method" inspection in IntelliJ IDEA.
* Number of different classes referenced from a class. In Java, this convention may be enforced with "Overly coupled class" inspection in IntelliJ IDEA.
* Number of fields in a class
* Number of functions in a class
* Number of lines of code in a class
* Number of classes in a package

### Arrangement of functions and fields

* Whether static members (fields, functions) must be all arranged before (or after) all non-static members in a class or static and non-static members could be interleaved.
* Whether fields must all be arranged before all functions in a class or fields and functions could be interleaved.
* Whether public members must be arranged before non-public members in a class or public and non-public members could be interleaved.
* Whether functions that don't modify the state of a class (getters) must be arranged before (or after) functions that modify the state of a class (setters) or getters and setters could be interleaved.
* Whether functions in a class that belong to some extended abstract class must be arranged in the same order as they are declared in the abstract class.
* What is the principle of function arrangement in a class (after all principles mentioned above which may be applied earlier). It may be:
** According to the order in which the functions are called: for example, function start is defined before finish
** Importance for understanding the class
** "Interestingness" of the functions
** Development risk: "trickiness" of functions, the probability of them containing bugs
** Runtime risk: the probability that something "bad" happens in the functions
** "Hotness": how often the functions are expected to be called, how important are they for the performance of the class
** Alphabetical order
* Whether functions are arranged in depth-first or breadth-first calling order. Examples:
Depth-first calling order:
Breadth-first calling order:
* Whether a (private) function that is called from multiple other functions should be arranged before all its callers, or after all its callers, or in a "subtree" of callees of the first (or the last) caller if depth-first calling order is used to arrange functions.

### Branch arrangement in if-else and switch statements

The criterion for arranging a branch higher in an if-else statement or a chain may be:
* Non-negativity in the if condition
* Importance for understanding the function
* "Interestingness" of the branch
* Size of the branch
* "Hotness": how often the branch is expected to be taken, how important is it for the performance of the function. In languages such as C and C++, the probability of the branches may be hinted to the compiler via macros such as likely and unlikely independently of the order of the branches, yet it still may be reasonable to use this convention to communicate the expected runtime behavior in the structure of the code.
In addition to the possible principles of branch arrangement in if-else statements listed above, the principle of case arrangement in switch statements may also be
* The alphabetical order of case expressions or variables
* The order of declaration of the enum values if they are used as the case constants.