The structure of a software system exists not only at the macro level of general architecture, but also at the micro level of the actual code. As systems grow larger and more complex, having a defined coding standard starts to pay dividends. Every programmer has his favourite style of coding, whether related to indentation, naming, brace styles, or new lines, but there’s a very simple rule to bear in mind when talking about coding standards on a project.
“Good coding standards are important in any development project, but particularly when multiple developers are working on the same project. Having coding standards helps ensure that the code is of high quality, has fewer bugs, and is easily maintained.“ – Zend Framework – Coding Standards
When you have more than one developer working a project, it’s easy to waste a lot of time having people reformat each other’s code. This is clearly a waste of developer resources and time. Having a standard that everyone agrees on saves time spent reformatting and makes it much easier for one developer to pick up and understand another developer’s code.
Since getting developers to agree on a coding standard is a difficult (if not impossible) task, the sensible way to achieve this goal is by creating a standard and forcing your developers to comply. At the start of your project, the lead developer or architect should sit down and document how code and files should be laid out. Any new developers to the project can then be presented with a copy of the document that, as well as coding standards, can act as a guide to reading the application source code.
What do we actually mean when we say that we need a coding standard? A coding standard is loosely defined as a set of rules that govern the structure of code from the smallest detail up to the entirety of the component or layer. A good coding standards document will contain guidance for naming of files, modules, functions, variables, and constants. In addition to describing the layout of the code at the small level, the document can also act as an official and easily referenceable guide to the overall component structure. When adding a feature to a component, the coding standards document should give a fairly clear idea of what file and module the feature belongs in, what its functions should be called, and how the calling system should look.
At the small scale, coding standards documents should contain stylistic guidelines for blocks and lines of code. This typically contains rules about the use of indentation, whitespace, brace positioning, comment style, and so on.
Indentation is usually the hottest topic for developers to disagree over. Do you indent with space or tabs? How many spaces or how wide are the tabs? Should code fall against the left margin? How are closing braces indented?
What whitespace should be included after conditional operators? Before opening braces? Between argument lists? Between binary operators?
How are braces laid out around else statements? Can braces be omitted for simple conditional statements? Should opening braces be on the same line as the conditional that opened them?
What kind of comment delimiters should be used? How should comments be laid out? What level of commenting is expected? How are functions introduced?
How are variables named? How are constants named? How are functions named? How about classes?
What should pages and templates be called? What should code libraries be named? Which folders do which files belong in?
Should files use DOS, Unix, or Mac line endings? Should files have UTF-8 byte order mark (BOM) sequences?
A document detailing all of your conventions, including examples to illustrate each one, should be added to your general documentation in source control. Every few months, you can revisit your document and see if it needs updatingas a project progresses, naming and file layout conventions sometimes need to evolve. If development has strayed from your document standards, then update the standards. Keeping the document up-to-date means that you can present it to any new developers and have them immediately start creating code that fits into your architecture and style.
This might seem like a lot of up-front work for no obvious benefit, so what’s in it for you? One benefit is that code that’s already been written will be easy to find. For example, if I want to find a function to add a tag to a photo in Flickr, I know where to look straight away, without having to be familiar with the code that the implementing developer wrote. Using a uniform naming convention for variables means that, when I receive a variable called $photo, I know exactly what it will contain. In a system without good variable naming convention, one programmer might be using $photo to store an ID, one might be using it to store an XML escaped photo title, while a third might be using it to store a photo database record hash.
The key point to remember is that it’s not important that you find the best style for your code structure and layout, but rather than your application maintains a consistent style. When your style and structure is consistent, it removes the space for simple mistakes and hugely reduces the cognitive overhead involved in understanding code written by other team members.
How to Design Your Class
When designing your classes, there is one golden rule: keep to real-world thinking. However, although that one rule sounds simple, it’s nebulouswhat exactly is real-world thinking? Fortunately there are a number of more simple rules you can follow that will help keep your code particularly readable:
- Start or end local properties with a special character, so that you are always clear about what variable is being set. The most common method is to start local properties with an underscore, e.g., _Name, _Age, etc.
- To follow OOP guidelines strictly, nearly all of your properties should be either private or protectedthey should not be accessible from outside of an object. More on this later.
- Write accessor methods to set and get private properties. These methods should be how you interface with the object. To get a property called _Age, write a method Age( ). To set a property called _Age, write a method SetAge( ).
- Always put properties and methods as low in your inheritance as they can go without repetition. If you find one object has properties and methods it is not supposed to have, you have gone wrong somewhere. For example, while dolphins can swim, gorillas cannot, so do not put a swim( ) method into a Mammal class just to save time.
If you are wondering why it is that accessor methods should be used to read and write properties, it is because OOP practice dictates that objects should be self-contained. That is, other parts of your program should be able to work with them using simple method calls, so that they do not need implicit knowledge of an object’s internal structures and operations.