You are on page 1of 49

Coding

The goal of the coding or programming activity is to implement the design in the best possible manner. During coding, it should be kept in mind that the programs should not be constructed so that they are easy to write but so that they are easy to read and understand.

discuss some programming practices and guidelines some common coding errors some processes that are followed while coding. Refactoring some verification methods, m metrics.

Programming Principles and Guidelines


The main task of a programmer is to write readable code with few bugs in it. Writing solid code is a skill that can only be acquired by practice. Common Coding Errors Much of effort in developing software goes in identifying and removing bugs. Some of the commonly occurring bugs are

A memory leak is a situation where the memory is allocated to the program which is not free. A software system with memory leaks keeps consuming memory, till the program may come to an exceptional halt because of the lack of free memory. char* foo(int s) { char *output; if (s>0) output=(char*) malloc (size); if (s==l) return NULL; /* if s==l then mem leaked */ return(output); }

Freeing an Already Freed Resource


In programs, resources are first allocated and then freed. ie memory is first allocated and then deallocated. This error occurs when the programmer tries to free the already freed resource.

main () {
char *str; str = (char *)malloc (10);

if (global==0) free(str) ; free (str) ; /* str is already freed

NULL Dereferencing
This error occurs when we try to access the contents of a location that points to NULL. This code segment shows two instances of NULL dereference.

char *ch=NULL; if (x>0) {


ch='c ' ;

} printf ("\%C" , *ch); /* ch may be NULL *ch=malloc(size); ch = 'c'; /* ch will be NULL if malloc returns NULL

Array Index Out of Bounds Array index often goes out of bounds Care needs to be taken to see that the array index values are not negative and do not exceed their bounds.

Arithmetic exceptions These include errors like divide by zero

Structured Programming The basic objective of the coding activity is to produce programs that are easy to understand. A program has a static structure as well as a dynamic structure. The static structure is the structure of the text of the program, a linear organization of statements of the program. The dynamic structure of the program is the sequence of statements executed during the execution of the program.

ie both the static structure and the dynamic behavior are sequences of statements; while the sequence representing the static structure of a program is fixed, the sequence of statements it executes can change from execution to execution.

the objective of structured programming is to write programs so that the sequence of statements executed during the execution of a program is the same as the sequence of statements in the text of that program.

As the statements in a program text are linearly organized, the objective of structured programming becomes developing programs whose control flow during execution is linearized and follows the linear organization of the program text.

The objective of linearizing the control flow can be achieved by making use of structured constructs.
In structured programming, a statement is not a simple statement, it is a structured statement.

The property of a structured statement is that it has a single-entry and a single-exit. during execution, the execution of the (structured) statement starts from one defined point and the execution terminates at one defined point. And if all statements are structured statements, then during execution, the sequence of execution of these statements will be the same as the sequence in the program text. Hence, by using single-entry and single-exit statements, the correspondence between the static and dynamic structures can be obtained.

single-entry and single-exit statements are Selection: if B then S1 else S2 if B then S1 Iteration: While B do S repeat S until B Sequencing: S1; S2; S3;... Do not use unstructured statements like break, continue.

Information hiding
When software is developed to solve a problem, the software uses some data structures to capture the information in the problem domain. A piece of information in the problem domain is used only in a limited number of ways in the problem domain. Any information in the problem domain typically has a small number of defined operations performed on it.

When the information is represented as data structures, only some defined operations should be performed on the data structures. This is the principle of information hiding. The information captured in the data structures should be hidden from the rest of the system, and only the functions should have access on the data structures that represent the operations performed on the information should be visible.

Coding Standards
Programmers spend more time reading code than writing code.

People other than the author also spend effort in reading code because the code is often maintained by someone other than the author.
Coding standards provide guidelines for programmers regarding naming, file organization, statements and declarations, and layout and comments.

Naming Conventions Package names should be in lowercase (e.g., mypackage). Type names should be nouns and should start with uppercase (e.g., Day, DateOfBirth). Variable names should be nouns starting with lowercase (e.g., name, amount). Constant names should be all uppercase (e.g., PI, MAX ITERATIONS).

Method names should be verbs starting with lowercase (e.g., getValue()).

Private class variables should have the suffix (e.g., private int value ). The term compute can be used for methods where something is being computed; the term find can be used where something is being looked up (e.g., computeMean(), findMin()). Exception classes should be suffixed with Exception (e.g., OutOfBoundException).

Files: conventions on how files should be named, and what files should contain, such that a reader can get some idea about what the file contains.

Java source files should have the extension .java


Each file should contain one outer class and the class name should be the same as the file name. Line length should be limited to less than 80 columns and special characters should be avoided. If the line is longer, it should be continued.

Statements: These are for the declaration and executable statements in the source code. Variables should be initialized where declared. Declare related variables together in a common statement. Use only loop control statements in a for loop. Loop variables should be initialized immediately before the loop. Avoid the use of break and continue in a loop.

Commenting and Layout: Comments are textual statements that help program reader to understand the code. Comments should explain what the code is doing or why the code is there. Comments should generally be provided for blocks of code. Comments for a module are often called prologue for the module, which describes the functionality and the purpose of the module

Single line comments for a block of code should be aligned with the code they are meant for. There should be comments for all major variables explaining what they represent.

Coding Process The coding activity starts when some form of design has been done and the specifications of the modules to be developed are available.

An Incremental Coding Process develop the code incrementally. write code for implementing only part of the functionality of the module. This code is compiled and tested with some quick tests to check the code that has been written so far. When the code passes these tests, the developer proceeds to add further functionality to the code, which is then tested again. Testing is done through test scripts that can be run easily.

Test-Driven Development Instead of writing code and then developing test cases to check the code, in TDD it is the other way around a programmer first writes the test scripts, and then writes the code to pass the tests. The whole process is done incrementally, with tests being written based on the specifications and code being written to pass the tests.

Pair Programming Here code is not written by individual programmers but by a pair of programmers. i.e one person will type the program while the other will constantly review what is being typed. When errors are noticed, they are pointed and corrected. Also the pair discusses the algorithms, data structures, or strategies to be used in the code to be written. The roles are rotated frequently making both equal partners and having similar roles.

In this we have the situation where the code is getting reviewed as it is being typed. i.e instead of writing code and then getting it reviewed by another programmer, we have a programmer who is constantly reviewing the code being written.

Refactoring
Coding often involves making changes to some existing code. Code also changes when requirements change or when new functionality is added. Due to the changes being done to modules, even if we started with a good design, with time we often end up with code whose design is not as good as it could be. Refactoring is the technique to improve existing code Refactoring involves changing the code to improve one of the design properties, while keeping the external behavior the same.

The basic objective of refactoring is to improve the design of code. Refactoring results in: 1. Reduced coupling 2. Increased cohesion 3. open-closed principle. Refactoring is not a technique for bug fixing or for improving code that is in very bad shape. It is done to code that is mostly workingthe basic purpose is to make the code live longer by making its structure healthier.

It starts with healthy code and instead of letting it become weak, it continues to keep it healthy. When is refactoring needed? There are some signs in the code, which are sometimes called bad smells that indicate that some of the desirable design properties may be getting violated If you smell one of these bad smells, it may be a sign that refactoring is needed. Some of these bad smells from are:

As code changes with time, to ensure that the code quality does not continue to degrade due to evolution, refactoring may be done. During refactoring no new functionality is added only improvement is done so that the design of the code improves by reduction of coupling, increase in cohesion

a) Duplicate Code: some small functionality is being executed at multiple places (e.g., the age from date of birth may be computed in each place that needs the date). Another reason is that when there are multiple subclasses of a class, then each subclass may end up doing a similar thing. b) Long Method: If a method is large, it often represents the situation where it is trying to do too many things. c) Long Class: Similarly, a large class may indicate that it is encapsulating multiple concepts, making the class not cohesive.

d) Long Parameter List: Complex interfaces are desirablethey make the code harder to understand and the complexity is a sign of improper design. e) Switch Statements: In object-oriented programs, if the polymorphism is not being used properly, it results in a switch statement where everywhere the behavior is to be different depending on the property. Presence of similar switch statements in different places is a sign that instead of using class hierarchy, switch statement is being used.

Presence of switch statement makes it much harder to extend codeif a new category is to be added, all the switch statements will have to be modified. f) Too Much Communication Between Objects: If methods in one class are making many calls to methods of another object to find out about its state, this is a sign of strong coupling. g) Message Chaining: One method calls another method, which simply passes this call to another object, and so on. This chain results in unnecessary coupling.

Verification Once a programmer has written the code for a module, it has to be verified before it is used by others. Code Inspections It is a technique in which defects are detected in the code not by executing the code but through a manual process.

The team for code inspection should include the programmer, the designer, and the tester.

The documentation to be distributed to the inspection team members includes the code to be reviewed and the design document. The aim of code inspections is to detect defects in code. Checklist is provided to inspectors to focus on type of defects Sample Checklist Do all the pointers point to some object? (Are there any "dangling pointers"?) Are all the array indexes within bound? Are all the branch conditions correct?

Will a loop always terminate (no infinite loops)? Is the loop termination condition correct? Where applicable, are the divisors tested for zero? Do actual and formal interface parameters match? Are all variables used? Are all output variables assigned?

Static Analysis analyzing the program text is called static analysis. Static analysis is performed by the aid of software tools. During static analysis the program itself is not executed, but the program text is the input to the tools. The aim of static analysis is to detect errors in the code and to generate information that can be useful in debugging.

Two approaches are possible. i) The first is to detect patterns in code that are "unusual" or "undesirable" and which are likely to represent defects. ii) The other is to directly look for defects in the code, that is, look for those conditions that can cause programs to fail when executing. i) The first form of static analysis is looking for unusual pattern in code. It also checks for redundancies. These redundancies are not detected by the compiler, and are caused due to carelessness in typing, lack of clear understanding of the logic,

Some of the redundancies the checkers identify are: Redundant assignments i.e when a variable is assigned some value but the variable is not used after the assignment Redundant conditionals, if a branching contains a condition that is always true or false, and hence is redundant. The second approach for static analysis is to directly look for errors in the programsbugs that can cause failures when the programs execute.

Many tools are available or have been developed software organizations. Among them one of the tool is PREfix Some of the errors PREfix identifies are: Using uninitialized memory Dereferencing NULL pointer Dereferencing invalid pointer returning pointer to freed memory Divide by zero

Unit Testing approach for verifying the code that a programmer is written. In unit testing, programs are executed with some test cases except that the focus is on testing smaller programs or modules called units. A unit may be a function, a small collection or functions, a class, or a small collection of classes. During unit testing the tester, who is generally the programmer, executes the unit for a variety of test cases and study the actual behavior of the units being tested for these test cases.

Based on the behavior, the tester decides whether the unit is working correctly or not. If the behavior is not as expected for some test case, then the programmer finds the defect in the program and fix it. For a functional unit, unit testing will involve testing the function with different test data as input. In this, the tester will select different types of test data to exercise the function.

test data includes some data representing the normal case, that is, the one that is most likely to occur. In addition, test data for special cases which might result in special or exceptional result. An issue with unit testing is that as the unit being tested is not a complete system but a part If in its execution it may use other modules that have not been developed yet. Due to this, unit testing often requires drivers or stubs to be written.

Drivers play the role of the "calling" module and are often responsible for getting the test data, executing the unit with the test data, and then reporting the result. Stubs are "dummy" modules that are used in place of the actual module to facilitate unit testing. Example: if a module M uses services from another module M' that has not yet been developed, then for unit testing M, some stub for M' will have to be written so M can invoke the services in some manner on M' so that unit testing can proceed.

Metrics For the code, the most commonly used metrics are size and complexity. Size Measures The main reason for interest in size measures is that size is the major factor that affects the cost of a project. The most common measure of size is the number of lines of code (LOC) finally delivered.

But the trouble with LOC is that the number of lines of code for a project depends on the language used.

For example, a program written in assembly language will be large compared to the same program written in a higher-level language Halstead proposed metrics for length and volume of a program based on the number of operators and operands. In a program some measurable quantities are defined: n1 is the number of distinct operators n2 is the number of distinct operands f1,j is the number of occurrences of the jth most frequent operator

f2,j is the number of occurrences of the jth most frequent operand vocabulary n of a program is defined as n = n1 + n2. Two new parameters are defined: N1 = f1,j , N2 = f2,j . N1 is the total occurrences of different operators in the program N2 is the total occurrences of different operands. The length of the program is defined as N = N1 + N2.

From the length and the vocabulary, the volume V of the program is defined as V = Nlog2(n).

You might also like