|
// Using both sides of the brain, and an open wiki
| |||
|
WIKI
|
Help:Coding GuidelinesThis document outlines the official coding guidelines of Cortex Creations. They must be followed strictly in any code distributed, sold, or created by Cortex Creations; either by volunteers, employees, or private contractors. Any code not following these guidelines must either be discarded or brought up to our standards. The goal of this document is to make code as easy as possible to read, comprehend, and modify; and provide a common foundation for programmers. This document currently contains the rules for these languages: Java, JavaScript, PHP, and C. Coming soon: rules for [X][HT]ML, CSS, and SQL.
Editor SettingsFontUse whatever font you'd like; we recommend you use a fixed width font such as Courier, Courier New, or Monaco. Monaco is preferable. Tabs and SpacesConfigure your editor to use hard tabs - not tabs emulated by several spaces. We recommend a tab width of 4 because it allows you to fit more code onto one line, and also makes code easier to read on smaller monitors/resolutions. Code must always be indented because it makes it much easier to follow, so having tab widths of much less than 4 can actually hurt readability. Linefeeds and NewlinesMake sure that your editor is saving files in the UNIX format. CommentsThe golden rule for all comments: keep them simple, short, and to the point. Comments should give a short description of what a block of code does: they shouldn't explain every single line. Writing clear, descriptive code is more important. That does not mean, however, that comments can be sloppy; each comment should be a sentence, within reason, and in 99% of the case at least capitalize the first letter. Single Line CommentsComments should be placed on the line before the code they are explaining. There should be a blank line before the comment (to separate it from other code) unless you are grouping statements. For example, comments in an IF, ELSE IF, ELSE series do not need to be separated from each other. On commenting if/else statements: before the first condition, state what the group of if/else statements is intended to do. Then the next line should say what conditions the first IF statement matches. With subsequent ELSE IF or ELSE statements, put what conditions the statement matches on the line before the statement. Bad Code: int num_bricks; // The number of total bricks on-screen is stored here
num_bricks = levels[current_level].num_bricks; // get number of bricks from current level
// Check if number of bricks is even or odd.
if (num_bricks % 2)
{
}
else
{
// Number of bricks is odd
}
Code: // The number of total bricks on-screen is stored here
int num_bricks;
// Get number of bricks from current level
num_bricks = levels[current_level].num_bricks;
// Check if number of bricks is even or odd. (NOTE: the purpose of ALL the IF/ELSE blocks)
// Is the number of bricks even? (NOTE: the purpose of the IF block is described here)
if (num_bricks % 2)
{
}
// The number of bricks is odd (NOTE: the purpose of the ELSE block is described here)
else
{
}Multiple Line CommentsMulti-line comments should be used only in the following situations, but as much as possible in these situations. Note: with multiline comments, always follow this format: Code: /** Start of the comment
* comment etc Each line of comment starts with a space, star, space
* etc
* etc
*/ Comment ends with space, star, slashAs a File HeaderFile headers are pretty simple. They should follow the format listed below. If you are using a Subversion server to hold files, the @subversion tag is very useful. If you have a certain attribute set in Subversion, the Subversion will automatically replace the $Id: $ section with information about that file. The @version tag should be used ONLY in the main or index file for your project. Include the @license tag for software projects, otherwise leave this out. Code: /**
* A short description of the file's purpose should go here.
* It can, of course, span multiple lines. Then, after this text,
* leave a blank line and then follow with meta-data about the file.
*
* @version: 0.5
* @started: Monday, September 10, 2001
* @copyright: Copyright (c) 2005, Cortex Creations, all rights reserved
* @website: http://www.cortex-creations.com
* @license: GPL
* @subversion: $Id: $
*/Before a Class ConstructWhen you put comments before a class construct, you should only show the class's description. Just some simple text describing the class, usage notes, whatever. Keep it simple. Bad Code: /**
* @class Template
* @package Utils
* @author Josh Gross
* @author Bob Somebody
* @version: 0.5.4
* @description This class is meant to act as a templating engine for PHP
* software. Only initialize one instance per page.
*/
class Template
{
}
Code: /**
* This class is meant to act as a templating engine for PHP
* software. Only initialize one instance per page.
*/
class Template
{
}Before a Function or Class MethodCode with no comments at all is bad, but only slightly worse than having more comments than code. The comments before a function should always multi-line and follow the format of comments before classes, as shown above. If you are writing APIs or libraries that will be commonly used, or want to generate HTML documents from comments (using phpDocumentor or JavaDoc) then just try to write better descriptions rather than a huge list of tags. Bad Code: class Template
{
/**
* @description This compiles a template file, following the Smarty template syntax.
* It parses through the whole file and returns generated PHP code.
* @param String pass in the file name here
* @return Well, this function doesn't really do anything yet
*/
function compile ($file_name)
{
}
}
Code: class Template
{
/**
* This compiles a template file, following the Smarty template syntax.
* It parses through the whole file and returns generated PHP code.
*/
function compile ($file_name)
{
}
}Before Large Groups of VariablesYou can also use multi-line comments before large groups of variables. There is no black and white with this issue; use your best judgement. It's acceptable to put multiline comments before variable declarations in a class, but try to group variables whenever possible. Use them sparingly, and only when you feel it's necessary for comprehension of large blocks of variables. In CSSMultiple-line comments can be used more liberally in CSS, since single line comment syntax does not exist. That being said, CSS code does not need as much commenting as code in other languages. Commenting Out CodeIf you need to comment out a large section of code, it is acceptable to use multiple-line comments, but those commented-out blocks of code should be removed as soon as possible. Code formattingCode structuresWe have a simple, concrete rule regarding curly brackets when being used to form a structure: put each bracket on a line by itself. Code after the opening bracket should be indented one tab, and the closing bracket should have the same indenting as the opening bracket. Bad Code: // Check for preferred condition
if (condition_is_true) {
alert(1);
// Fall back on acceptable condition
} else if (other_condition_is_true)
{
alert(2);
}
// Failure! Whine and moan
else alert(3);
Code: // Check for preferred condition
if (condition_is_true)
{
alert(1);
}
// Fall back on acceptable condition
else if (other_condition_is_true)
{
alert(2);
}
// Failure! Whine and moan
else
{
alert(3);
}Code Block SyntaxWhen defining and declaring code blocks (namely IF blocks and function declarations), there should be a single space between the keywords or function name and any parentheses. When calling a function, do not include the space. Bad Code: function do_something(var)
{
window.alert ( var );
}
if(condition)
{
do_something( condition2 );
}
else if(condition2)
{
do_something (condition);
}
Code: function do_something (var)
{
window.alert(var);
}
if (condition)
{
do_something(condition2);
}
else if (condition2)
{
do_something(condition);
}Optional curly brackets?Some languages permit you to omit curly brackets when only one command is inside a conditional structure. Always use curly brackets. Failure to do so makes code inconsistent and error-prone. Bad Code: if (1) do_first_thing();
else if (2) do_second_thing();
else do_backup_thing();
Code: if (1)
{
do_first_thing();
}
else if (2)
{
do_second_thing();
}
else
{
do_backup_thing();
}Optional Semicolons?Some languages (primarily Javascript) do not force you to use semicolons at the end of every line. It is VERY bad style to omit semicolons; use them wherever it would be required in any other language. Using "and" and "or" keywordsDon't do it. When using the "and" and "or" operators in conditional statements, ALWAYS use the symbols && and ||, not the keywords and and or. Using the keywords make conditional statements hard to glance over; it makes code lengthier; and it tends to be an inconsistent practice. Bad Code: if ((condition_one and condition_two) or (condition_three and condition_four))
{
do_something_big();
}Code: if ((condition_one && condition_two) || (condition_three && condition_four))
{
do_something_big();
}Breaking Up Long ConditionalsYou should break up long conditionals (inside of if, else if, while, and for declarations) that can't fit into one line. If a line of conditionals exceeds about 100 characters, you should break it up. When you do so, try to keep parenthetical structures on one line, unless one needs to be split in half. Always place logic symbols (&& and ||) at the beginning of a line, rather than the end of a line. Whenever you split a condition to the next line, it should be indented. If you are breaking up conditions in the middle of a parenthetical expression, the line should be indented according to the depth of parenthesis nesting. Bad Code: if ((condition_one && condition_two) || (condition_three && condition_four) || (condition_five && condition_six) || (condition_seven && condition_eight))
{
}
Code: if ((condition_one && condition_two) || (condition_three && condition_four) ||
(condition_five && condition_six) || (condition_seven && condition_eight))
{
}
if ((condition_one && condition_two) || (condition_three &&
condition_four) || (condition_five && condition_six) || (condition_seven && condition_eight))
{
}
if ((condition_one && condition_two) || (condition_three && condition_four)
|| (condition_five && condition_six) || (condition_seven && condition_eight))
{
}Breaking Up Long StringsWhen the line a string is defined on exceeds about 100 characters in length, the string should be split in half. In whatever languages possible, the concatenation operator should be the first symbol on a line before continuing a string (rather than the last symbol on the previous line). There should then be a single space between the concatenation operator and the continued string. This is NOT possible in C, where the backslash needs to be the last character on the previous line. Furthermore, when splitting up sentences and paragraphs in half, single spaces should NOT appear at the end of lines, they should appear on the next line at the beginning of the continued string. Pay close attention to the examples below. PHP, JavaScript/Java-type syntaxBad Code: $string_var = 'this is a really long string. this is a really long string. this is a really long string. this is a really long string. ';
string_var = "this is a really long string. this is a really long string. this is a really long string. this is a really long string. ";
Code:
$string_var = 'this is a really long string. this is a really long string.'
. ' this is a really long string. this is a really long string. ';
string_var = "this is a really long string. this is a really long string."
+ " this is a really long string. this is a really long string. ";C syntaxBad Code: char* string_var = "this is a really long string. this is a really long string. this is a really long string. this is a really long string. ";
Code: char* string_var = "this is a really long string. this is a really long string."\
" this is a really long string. this is a really long string. ";Breaking up PHP/JavaScript array definitionsWhen an array definition in PHP or JavaScript exceeds 100 characters and cannot fit wholly on one line, you should split it up. When splitting it up, follow the same rule with the array brackets/parentheses as with curly brackets: each one alone on a line. The same applies with nested arrays. In some cases, usually with less complex arrays, you can still have several array values on one line. For more complex arrays, especially ones that need to be editable or readable easily, put each value on a separate line. PHPBad Code: $var = array(0 => 'this', 1 => 'is', 2 => 'a', 3 => 'really', 4 => 'really', 5 => 'long', 6 => 'array');
$var = array(
0 => 'this', 1 => 'is', 2 => 'a', 3 => 'really', 4 => 'really', 5 => 'long', 6 => 'array');
$var = array(
0 => 'this', 1 => 'is', 2 => 'a', 3 => 'really', 4 => 'really', 5 => 'long', 6 => 'array'
);
$var = array(0 => 'this', 1 => 'is', 2 => 'a', 3 => 'really',
4 => 'really', 5 => 'long', 6 => 'array');
Code: $var = array
(
0 => 'this',
1 => 'is',
2 => 'a',
3 => 'really',
4 => 'really',
5 => 'long',
6 => 'array'
);JavaScriptBad Code: var ary = ['this', 'is', 'a', 'really', 'really', 'long', 'array', 'this', 'is', 'a', 'really', 'really', 'long', 'array', 'this', 'is', 'a', 'really', 'really', 'long', 'array'];
var ary = {0: 'this', 1: 'is', 2: 'a', 3: 'really', 4: 'really', 5: 'long', 6: 'array', 7: 'this', 8: 'is', 9: 'a', 10: 'really', 11: 'really', 12: 'long', 13: 'array'};
Code: var ary =
[
'this', 'is', 'a', 'really', 'really', 'long', 'array', 'this', 'is'
'a', 'really', 'really', 'long', 'array', 'this', 'is', 'a', 'really', 'really', 'long', 'array'
];
var ary =
{
0: 'this',
1: 'is',
2: 'a',
3: 'really',
4: 'really',
5: 'long',
6: 'array',
7: 'this',
8: 'is',
9: 'a',
10: 'really',
11: 'really',
12: 'long',
13: 'array'
};Splitting up Ternary ExpressionsWith ternary expressions it's nice to have everything on one line. However, if the conditionals or statements are long or complex, and especially if they exceed 100 characters in length, you should split them up. As always, an operator (rather than statement) such as a question mark or colon should be the first thing on the beginning of a line continuing a split ternary expression. Code: $value = ($short_condition ? $short_expression_1 : $short_expression_2);
Bad Code: $value = ($really_long_condition && $really_long_condition_2 ? $really_long_expression_1 * $really_long_expression_3 : $really_long_expression_2 * $really_long_expression_3);
Code: $value = ($really_long_condition && $really_long_condition_2
? $really_long_expression_1 * $really_long_expression_3
: $really_long_expression_2 * $really_long_expression_3);
Bad Code: $value = (($really_long_condition && $really_long_condition_2) || ($really_long_condition_3 && $really_long_condition_4) || ($really_long_condition_5 && $really_long_condition_6) ? $really_long_expression_1 * $really_long_expression_3 : $really_long_expression_2 * $really_long_expression_3);
Code: $value = (($really_long_condition && $really_long_condition_2)
|| ($really_long_condition_3 && $really_long_condition_4
|| ($really_long_condition_5 && $really_long_condition_6)
? $really_long_expression_1 * $really_long_expression_3
: $really_long_expression_2 * $really_long_expression_3);
Naming ConventionsTo ensure consistency, the naming conventions are slightly different from language to language, as described below. The main goal with naming functions, classes, structures, and variables is to come up with good, descriptive names; and names that are short, easy to remember, read, and type. Function/method names should always be verbs (do_something) and variable/class names should be nouns. Here are some examples of good and bad names: Bad Code: $number = get_number($id);
Code: $number_of_users = get_number_of_users($group_id);
$group_members = get_number_of_users($group_id);Class NamesName the class after what it is, plain and simple. If it can't be plain and simple, that's a problem with your class and not your ability to come up with good names. If you can't think of a good name you may need to split up the class. Even more so, having compound names of over three words usually means that the class is too complicated. Avoid the temptation of bringing the name of the class a class derives from into the derived class's name. A class should stand on its own. It doesn't matter what it derives from. Bad Code: class TemplateAndEmailFormatter { ... }
Code: class Template { ... }
class EmailFormatter { ... }Naming style: camelCase/interCappingFor Java and JavaScript code, you should use the interCapping style for all names. That is, the first word of the name is all lowercase: the first letter in each subsequent word should be capitalized. The only time when the capitalization rules may be ignored is when prefixing the name of a product, library, etc. In this case, there should be an underscore between the "name" prefix and the rest of the variable/function/class name. The first letter in every word of class or package names should be capitalized. This helps distinguish classes from variable and function names. Code: // Product names
function WebDDM_getElement();
function phpJSO_decodeCompressedScript();
// Classes
class TemplateEngine
{
}
// Other names
WebDDM_browserVersion = X;
function compressCode (code)
{
var compressedCode = code;
compressedCode = '';
return compressedCode;
}Naming style: under_scoresFor PHP and C code, you should use the under_scored style for all names. Each word in a name should be separated by an underscore, and all letters should be all lowercase. The only time when the capitalization rules may be ignored is when prefixing the name of a product, library, etc. The first letter in every word of class names should be capitalized. This helps distinguish classes from variable and function names. Code: // Product names
function WebDDM_get_element();
function phpJSO_decode_compressed_script();
// Classes
class Template_Engine
{
}
// Other names
$WebDDM_browser_version = X;
function compress_code ($code)
{
$compressed_code = $code;
$compressed_code = '';
return $compressed_code;
}ConstantsIn all languages, no matter what style is consistent with the language, constants should always be in ALL CAPS and have each word separated by an underscore. Code: // PHP
define('USER_STUDENT', 1);
// C
#define USER_STUDENT 1
// Java
class XYZ
{
final int USER_STUDENT = 1;
}File NamingWhen naming files: always use ".php" for PHP files, ".c" for C code, ".h" for C header files, ".java" for Java files, ".js" for JavaScript files, and ".css" for CSS files. Miscellaneous guidelinesReferring to constantsIt's bad style to use special code words/numbers in code without defining constants. Notice how in the first example, extra comments are necessary to explain the numbers. If the numbers ever need to change, it can be a nightmare (and sometimes even impossible) to track down all occurances of usage. No magic numbers. A magic number is a bare-naked number used in source code. It's magic because no one has a clue what it means... including the authors after 3 months. Bad Code: // Check if user has proper authorization to do XYZ
// User must be admin or a teacher at the current school
if ($user_data['user_type'] == 2 || ($user_data['user_type'] == 1 && $current_school_id == $user_data['school_id']))
{
// Do something
}
Code: // Defined in a separate file...
define('USER_TEACHER', 1);
define('USER_ADMIN', 2);
// Check if user has proper authorization to do XYZ
if ($user_data['user_type'] == USER_ADMIN || ($user_data['user_type'] == USER_TEACHER && $current_school_id == $user_data['school_id']))
{
// Do something
}
SecuritySecurity rules for all Cortex Creations projects:
|
||
|
Please see the license for using content on this wiki.
Find out about this wiki and read our disclaimer. Copyright © 2001-2006, Cortex Creations, LLC, All Rights Reserved | |||