Coding in Software Engineering
Coding is undertaken once the design phase is complete and the design documents have been successfully reviewed.
In the coding phase, every module specified in the design document is coded and unit tested.
During unit testing, each module is tested in isolation from other modules. That is, a module is tested independently as and when its coding is complete.
After all the modules of a system have been coded and unit tested, the integration and system testing phase is undertaken.
Integration and testing of modules is carried out according to an integration plan.
The integration plan, according to which different modules are integrated together, usually envisages integration of modules through a number of steps.
During each integration step, a number of modules are added to the partially integrated system and the resultant system is tested.
The full product takes shape only after all the modules have been integrated together.
System testing is conducted on the full product. During system testing, the product is tested against its requirements as recorded in the SRS document.
The input to the coding phase is the design document produced at the end of the design phase.
The design document contains not only the high-level design of the system in the form of a module structure (e.g., a structure chart), but also the detailed design.
The detailed design is usually documented in the form of module specifications where the data structures and algorithms for each module are specified.
During the coding phase, different modules identified in the design document are coded according to their respective module specifications.
Objective of the Coding Phase
The objective of the coding phase is to transform the design of a system into code in a high-level language, and then to unit test this code.
Normally, good software development organisations require their programmers to adhere to some well-defined and standard style of coding which is called their coding standard.
These software development organisations formulate their own coding standards that suit them the most, and require their developers to follow the standards rigorously because of the significant business advantages it offers.
The main advantages of adhering to a standard style of coding are the following:
A coding standard gives a uniform appearance to the codes written by different engineers.
It facilitates code understanding and code reuse. It promotes good programming practices.
A coding standard lists several rules to be followed during coding, such as the way variables are to be named, the way the code is to be laid out, the error return conventions, etc.
It is mandatory for the programmers to follow the coding standards.
Compliance of their code to coding standards is verified during code inspection.
Any code that does not conform to the coding standards is rejected during code review and the code is reworked by the concerned programmer.
In contrast, coding guidelines provide some general suggestions regarding the coding style to be followed but leave the actual implementation of these guidelines to the discretion of the individual developers.
After a module has been coded, usually code review is carried out to ensure that the coding standards are followed and also to detect as many errors as possible before testing. It is important to detect as many errors as possible during code reviews, because reviews are an efficient way of removing errors from code as compared to defect elimination using testing.
Coding Standards and Guidelines
Good software development organisations usually develop their own coding standards and guidelines depending on what suits their organisation best and based on the specific types of software they develop.
To give an idea about the types of coding standards that are being used, we shall only list some general coding standards and guidelines that are commonly adopted by many software development organisations, rather than trying to provide an exhaustive list.
Representative coding standards
Rules for limiting the use of globals:
These rules list what types of data can be declared global and what cannot, with a view to limit the data that needs to be defined with global scope.
Standard headers for different modules:
The header of different modules should have standard format and information for ease of understanding and maintenance.
The following is an example of header format that is being used in some companies:
- Name of the module.
- Date on which the module was created.
- Author’s name.
- Modification history.
- Synopsis of the module.
- This is a small writeup about what the module does.
- Different functions supported in the module, along with their input/output parameters.
- Global variables accessed/modified by the module.
Naming conventions for global variables, local variables, and constant identifiers:
- A popular naming convention is that variables are named using mixed case lettering.
- Global variable names would always start with a capital letter (e.g., GlobalData)
- Local variable names start with small letters (e.g., localData).
- Constant names should be formed using capital letters only (e.g., CONSTDATA).
Conventions regarding error return values and exception handling mechanisms:
The way error conditions are reported by different functions in a program should be standard within an organisation.
For example, all functions while encountering an error condition should either return a 0 or 1 consistently, independent of which programmer has written the code.
This facilitates reuse and debugging.
Representative coding guidelines:
The following are some representative coding guidelines that are recommended by many software development organisations.
Do not use a coding style that is too clever or too difficult to understand:
Code should be easy to understand. Many inexperienced engineers actually take pride in writing cryptic and incomprehensible code.
Clever coding can obscure the meaning of the code and reduce code understandability; thereby making maintenance and debugging difficult and expensive.
Avoid obscure side effects:
The side effects of a function call include modifications to the parameters passed by reference, modification of global variables, and I/O operations.
An obscure side effect is one that is not obvious from a casual examination of the code.
Obscure side effects make it difficult to understand a piece of code.
For example, suppose the value of a global variable is changed or some file I/O is performed obscurely in a called module.
That is, this is difficult to infer from the function’s name and header information. Then, it would be really hard to understand the code.
Do not use an identifier for multiple purposes:
Programmers often use the same identifier to denote several temporary entities.
For example, some programmers make use of a temporary loop variable for also computing and storing the final result.
The rationale that they give for such multiple use of variables is memory efficiency, e.g., three variables use up three memory locations, whereas when the same variable is used for three different purposes, only one memory location is used.
However, there are several things wrong with this approach and hence should be avoided.
Some of the problems caused by the use of a variable for multiple purposes are as follows:
Each variable should be given a descriptive name indicating its purpose.
This is not possible if an identifier is used for multiple purposes.
Use of a variable for multiple purposes can lead to confusion and make it difficult for somebody trying to read and understand the code.
Use of variables for multiple purposes usually makes future enhancements more difficult.
For example, while changing the final computed result from integer to float type, the programmer might subsequently notice that it has also been used as a temporary loop variable that cannot be a float type.
Code should be well-documented:
As a rule of thumb, there should be at least one comment line on the average for every three source lines of code.
Length of any function should not exceed 10 source lines:
A lengthy function is usually very difficult to understand as it probably has a large number of variables and carries out many different types of computations.
For the same reason, lengthy functions are likely to have a disproportionately larger number of bugs.
Do not use GO TO statements:
Use of GO TO statements makes a program.