Code Standards: Why and What?

by pschwisow

This is the first part in a multi-part series on code standards. I’ll start by laying out why we need them and what things actually comprise a code standard. Examples are in PHP, but most concepts are language-agnostic. Future installments will go into detail about different aspects of code standards and how to define them and use them to improve your team’s code.

Why Do We Need Code Standards?

There are many reasons to follow an agreed upon set of code standards:

  • the boss / senior engineer said to
  • that’s what “real” engineers do
  • it looks better

All three of those statements may have some validity for some of you, but there are some very practical reasons that are not dependent on your unique situation. Let’s look at an example…

function convert($data){
$l = strlen($data)-2;
$str = substr($data,1,$l);
$a = explode(",",$str);
$a2 = array();
for ($i=0;$i<sizeof($a);$i++) {
$l2 = strlen($a[$i])-2;
$a2[] = substr($a[$i],1,$l2);
}
return $a2;
}

Well, that’s a rather ugly piece of code, isn’t it? Maybe so, but “ugly” is a subjective term. To adapt an old expression, ugly is in the eye of the beholder. What is actually wrong with the way this code is written?

It’s hard to read. Everything is jammed along the margin. Most PHP developers (and those who work in any language with a C-like language) have come to expect indenting to signify the beginning and ending of statement-groups. Without that context, it’s hard to keep our place while reading the code. In this small example, it may be possible to work around it, but as the size of the code snippet we’re looking at increases, this becomes more and more difficult.

It’s hard to understand. Variable names provide little insight into what type of data they contain and what the significance of that data is. The function is named convert, but… Convert from what? Convert to what?

As a result of those two direct problems, there is also a third problem: Problems in the code are hard to spot. If we spent a large amount of our mental efforts just figuring out where we are in the code and what is happening, then it can be very difficult to focus on whether the results are actually correct.

Let’s see if we can address some of those problems…

function jsonStringsToArray($jsonData)
{
    // remove first and last []
    $length = strlen($jsonData) - 2;
    $jsonString = substr($jsonData, 1, $length);

    // tokenize, using , as a divider
    $newArray = explode(",", $jsonString);

    $lastArray = array();
    for ($i = 0; $i < sizeof($newArray); $i++) {
        $thisLength = strlen($newArray[$i]) - 2;
        $lastArray[] = substr($newArray[$i], 1, $thisLength);
    }
    return $lastArray;
}

That’s better. The code uses indents to set off different sections. Space within lines makes it clear where a variable name ends and an operator begins. Variables are named clearly, so you can immediately get a sense of how they fit in. We even have a couple comments that make it clear what is happening on a few lines that may not be intuitively obvious. It should be much clearer what’s happening inside the function.

One more thing…

/**
 * Converts JSON data string to PHP array.
 * 
 * Assumes this format: ["Some text","Even more text"]
 * 
 * @param string $jsonData
 * @return array
 */
function jsonStringsToArray($jsonData)
{
    // remove first and last []
    $length = strlen($jsonData) - 2;
    $jsonString = substr($jsonData, 1, $length);

    // tokenize, using , as a divider
    $newArray = explode(",", $jsonString);

    $lastArray = array();
    for ($i = 0; $i < sizeof($newArray); $i++) {
        $thisLength = strlen($newArray[$i]) - 2;
        $lastArray[] = substr($newArray[$i], 1, $thisLength);
    }
    return $lastArray;
}

With a well-formatted comment for the method as a whole, we know why this function exists, what assumptions it has about the incoming data, and a clear definition of what the input and output types are. (This style of comment is called a “docblock”. I’ll cover that in more detail in a future installment of this series.)

So now we know the what, how, and why of this function. Astute readers may realize a fundamental problem with the function: The function itself re-implements functionality that already exists in PHP’s built-in json_decode function. Furthermore, it is an incomplete implementation of its functionality that only works if the input represents an array of strings.

By defining and enforcing sensible standards, we strive to ensure the quality of our code and maintain confidence when deploying it.

What Areas Should Standards Address?

There are many different areas we should consider when drafting our standards. We’ve seen a few that relate directly to code, but standards should go beyond just PHP. Consider creating standards for any aspect of your software and process. (Note that I said “consider”. Don’t go overboard and create standards for things that have little or no impact on the quality of our team’s work.)

A good list to get you started thinking about your standards:

  1. Naming Practices – Consider both technical aspects of naming (camelCase or snake_case) and subjective aspects (“names should be verbose enough to be informative”).
  2. Code Formatting – Use of indents, vertical space, and space within lines. Placement of parentheses and braces.
  3. File Structure – One class per file, don’t define and execute in the same file.
  4. Autoloading – What type of autoloading do we use? This will also overlap with naming practices and file structure standards.
  5. Application File Structure – How do we lay out the application? What are the top-level directories? What does each contain?
  6. Separation of Concerns – Do we follow model-view-controller? Action-domain-responder?
  7. Consistent Architectural Patterns – What is the overall structure of our application? What does a controller look like? How do we talk to the database?
  8. Documentation Standards – Consider both in-file documentation (i.e. comments) and separate documentation (user documentation, developer documentation, API documentation).
  9. Testing Standards – What kinds of tests should we have? What should be covered?
  10. Version Control Standards – What VCS do we use? What is our branching model? Do we merge or rebase? Should commits be small and narrow in scope or should all changes for one issue be squashed into a single commit?
  11. Process Standards – How does work get broken down into manageable “stories”? Who prioritizes the “stories”? How does a “story” move from “open” to “done”? What do we do to confirm that work is correct and meets quality standards? How do we deploy completed work?

That is admittedly quite a sizeable list. You likely already have some standards in many of those areas, though they may be unofficial and unwritten. Start by taking an inventory of what standards you already have (even if they are not entirely consistent with each other). Next time we’ll go into more detail about how to firm up what you have and define standards in areas that you’re currently lacking.

Advertisements