Skip to content

Coding Standards

Tyree edited this page Jan 8, 2014 · 7 revisions

This document contains the coding standards for the AtomicStack projects. It contains both style guidelines and best practices for various middle tier and client front end code and other assets. This document was written using the Coding Guidelines - Mono as an outline.

Style Guidelines (c#)

Please adhere to the following guidelines so that we may maintain a seamless and consistent prose throughout the code base. Please try to follow these guidelines to ensure prettiness.

Indentation

Use 4 space tabs for writing your code. Since we are using 4 space tabs nesting won't be as much of a problem as if we were using 8 space tabs. However, it is still a good idea to use short circuitting techniques to reduce nesting.

Switch statements have the case indented one level in from the switch.

switch (x)
{
    case 'a':
        // do something
    case 'b':
        // do some other thing
}

All code within blocks are indented one level in from its enclosing braces.

{
    // do something
}

Tab Stops

Tab stops are considered to occur at every 4th column (1,5,9,13,17,21,etc.). Tab stops are used to provide easy column type visual scanning of important varying details of similar constructs. The use of options and an IDE that supports current line highlighting is recommended to bridge individual lines that may be wider than normally expected due to adherence to the following Tab Stop guidelines.

Declaration statements that are grouped together should have the data types and variable names lined up to the same tab-stop. Assignment statements grouped together should have the assignment operator (= sign) lined up to the same tab-stop. These guidelines are compounded when assignments are performed in declaration statements. For example:

private     int                 someIntegerValue        = 0;
public      SomeDefinedType     someDefinedTypeInstance = new SomeDefinedType();
internal    string              someStringValue         = String.Empty;

Braces

We are generally following the Allman Style for braces containing multiline blocks. This means that all opening and closing brace pairs are expected to line up on the same tab stop when not occurring on the same line. Each nested block is expected to indent to the next tab stop. Vertical spacing should not be much of an issue within this project since we should be adhering to clean coding principles which should result in very small, lightweight functions with very low cyclomatic complexity. Despite this, braces may be omitted when the control statement is followed by a singular affected statement or a set of statements that chain back to the control statement. Also, brace pairs may be placed on the same line for single line functions and property methods. For example, all of the following are considered proper within these guidelines:

public  int    SomeIntegerValue    { get { return 0; } }
public  int    Add(int x, int y)   { return x+y; }
if (true)
for(;;) Debug.write("Does this code ever stop running?");
if (true)
{
    for(;;) Debug.write("Does this code ever stop running?");
}
if (true)
{
    for(;;)
    {
        Debug.write("Does this code ever stop running?");
    }
}
if (true)
{
    for(;;)
    {
        switch (true)
        {
            case (false):
                break;
            default:
                Debug.write("Does this code ever stop running?");
        }
    }
}

The following examples are not considered proper within these guidelines:

if (true) {
    for(;;) {
        Debug.write("Does this code ever stop running?");
    }
}
if (true) {
    for(;;) {
        Debug.write("Does this code ever stop running?");}}
if (true)
    {
    for(;;)
        {
        switch (true)
            {
            case (false):
                break;
            default:
                Debug.write("Does this code ever stop running?");
            }
        }
    }

Generics Parameters/Arguments

When you need to wrap Generic parameter declarations and type arguments, wrap the opening angle bracket to the next line and the same tab stop as the Generic type. Then wrap the first parameter/argument onto the next line and indented to the next tab stop. Wrap all other parameters to new lines and the same tab stop. Wrap the closing angle bracket to the next line and the same tab stop as the opening angle bracket. The following examples are considered proper within these guidelines.

public
partial class   Entity
                <
                    tCriteria,
                    tModification,
                    tSelection
                >
        where   tCriteria   : Entity<tCriteria, tModification, tSelection>.EntityCriteria
{
}
public
abstract
partial
class       IndexedList<tIndexedList, tIndexKeyType, tIndexedItem>
:
            Atom
            <
                tIndexedList, 
                System.Func
                <
                    tIndexedItem, 
                    IndexedList
                    <
                        tIndexedList, 
                        tIndexKeyType,
                        tIndexedItem
                    >.KeyProperty
                >
            >,
            IList<tIndexedItem>, 
            IXmlSerializable
where       tIndexedList                : IndexedList<tIndexedList, tIndexKeyType, tIndexedItem>
where       tIndexKeyType               : System.IEquatable<tIndexKeyType>
{
}
public  IndexedList
        (
            System.Func
            <
                tIndexedItem, 
                KeyProperty
            >                   getKeyProperty
        ) 
:
        base(getKeyProperty)                            { this.getKeyProperty = getKeyProperty; }

The following is not considered proper according to these guidelines:

public
partial class   Entity<tCriteria, tModification,
                tSelection>
        where   tCriteria   : Entity<tCriteria, tModification, tSelection>.EntityCriteria
{
}
public
abstract
partial
class       IndexedList<tIndexedList, tIndexKeyType, tIndexedItem> : Atom<tIndexedList, System.Func
            <tIndexedItem, IndexedList<tIndexedList, tIndexKeyType, tIndexedItem>.KeyProperty>>,
            IList<tIndexedItem>, IXmlSerializable
where       tIndexedList                : IndexedList<tIndexedList, tIndexKeyType, tIndexedItem>
where       tIndexKeyType               : System.IEquatable<tIndexKeyType>
{
}

Multiline Parameters

When you need to wrap parameters across multiple lines, wrap the opening parenthesis to the next line and same tab stop as the method name. Then wrap the first parameter onto the next line and indented to the next tab stop. Wrap all other parameters to new lines and the same tab stop. Wrap the closing parenthesis to the next line and the same tab stop as the opening parenthesis. The following examples are considered proper within these guidelines.

public  int Add
            (
                int x, 
                int y
            )          { return x+y; }
public  int Add
            (
                int x, 
                int y
            )
{
    return x+y;
}

The following examples are not considered proper within these guidelines:

public  int Add (int x, 
                int y
                )          { return x+y; }
public  int Add(int x, 
                int y)
{
    return x+y;
}

File Headers

TBD

Multiline Comments

TBD

Casing

TBD

Field/Property/Method Contexts (this)

TBD

Line lengths

TBD

Object initialization

TBD

Concise But Descriptive Enough Identifiers

TBD

Best Practices

The following practices are strongly encouraged and should be adhered to.

Separation of Concerns

Please review the following Wikipedia page on the topic of Separation of Concerns.

Clean Coding

On the subject of clean coding, please refer to the following blog post by Cory House as to why it is important. You might also want to consider checking out his pluralsight course Clean Code: Writing Code for Humans.

Tier Down Design and Development

This topic is one that there may not be an appropriate resource for. There will be an upcoming post or two regarding this evolutionary approach to designing and developing applications. The posts will cover the use of functional prototyping to facilitate the creation of high fidelity prototypes whose functionality and behavior are theoretically indistinguishable from a more complete implementation without all of the effort of such. They will also cover the artifacts produced at each boundary and how this helps to reduce the effort in designing a complete system without continually returning to the drawing board and without requiring one to keep the big picture in mind all of the time.