June 29, 2006

Javaref

Filed under: Java

I think Javaref (via Ajaxian) displays one of the best uses of AJAX. It has injected usability and ease in refering to the Java documentation.

So welcome to the Web 2.0 JavaDoc. The default way of looking up is searching. This is made easier with features like autocomplete.

Java API documentation are displayed in a style that is radically different from the classic javadoc style that ships with the JDK. The documentation includes class source code (where available), ability to leave user notes and ability to transparently navigate between APIs by following code references.

However, the drawback is that it does not have Sun’s JDK documentation, as mentioned in the FAQ.

I hope even gotAPI follows this.

Tags: , , ,

June 19, 2006

Importance Of Coding Standards

Filed under: commons

Dr. Dobb’s Portal has an article on code quality improvement via coding standards conformance. The concept of coding standards is considered a part of development best practices but the way it is implemented is a pet subject for controversy. In some cases improper coding standards policies have been known to be harmful or less productive.

Purpose

The purpose of implementing a coding standard is to make the code homogeneous throughout the project so that is more maintainable. If it was that once written the code is never looked into, the value of coding standards would diminish. However, the reality is that code has bugs, which might be solved by others, a software evolves through its entire product cycle which leads to evolution and reuse of code on existing base. If the code is presented with consistency, it is easier to read and understand it, even by someone else.

This means that coding standard is not only about naming conventions. It should define how a block of code should look like, it should define indentation and policies to avoid generation of complex code like using multiple or nested ifs or incomprehensible loops. e.g., switch/select-case instead of a huge block of if-else if-else might be useful in languages like C++ and Java. Today all the higher languages support multiple constructs for flow control.

For Whom?

Ideally coding standards should be used by everyone in every project. However, its perceptible value might change depending on the size and the skill set. Even in a one-man project, coding standards help in keeping it clean over a longer period of time, but in larger projects they are a must. It is a requirement today to have people of varying skills in a project. Coding standards keep everyone on the same page and make the code comprehensible to everyone.

Coding standards become of prime importance for an open and distributed team. A lot of open source projects accept contributions from volunteers and users, the project will become a disaster if coding standards are not enforced. A good example is coding conventions put forth by Velocity.

The Problem

There are two main reasons why coding standards are opposed to:

  • Clash with personal style: A lot of engineers develop their own style of programming, which might be best for themselves. However, in a team it might not be very fruitful. An individual should adopt what is good for the team, whether it clashes with personal style or not.
  • Too much work: Using the coding standards feels too much work if its value is not being seen. And this is true sometimes. Wrong policies can often lead to increase in time and effort without an equivalent increase in value.

The Solution

The best way to solve these problems is to include all the team members when the coding standards are formulated. If it not possible to include everyone, all should at least be educated on the coding standards and their advantages and asked for their feedback.

Coding standards, just like software processes, should be customized for every project. Different aspects of the project like team size, team skillset, deadline, project, nature (distributed, onsite/offshore, …) should be considered. Using one-for-all coding standards usually results in misalignment between the actions and project’s goal. Sometimes this can also require customization to project management or organizational techniques.

A project configuration contains multiple policies and coding standards might overlap with some of them, e.g., exception-handling policy is closely related with coding standards. Specific care should be taken so that they don’t clash with each other.

Various tools are available to check compliance with coding standards. However, tools can never ensure the absolute. The best thing is to conduct code reviews, either by peers or seniors and encourage interaction in the developers.

Some more reading:

Tags: , , ,

June 14, 2006

Resource Acquisition Is Initialization

Filed under: commons, CPP

Software programs have to deal with resources (memory, files, mutexes, semaphores, database connections, …) that a computer provides. To be able to make sure that the resources are available to all the programs and optimally used, following steps are required to use a resource:

  • Acquire a resource
  • Use the resource
  • Release the resource

By acquiring and releasing the program stakes its claim to the resource. If the resource is not released it usually ends up causing memory leaks, deadlocks or sometimes crashes. Memory is the most commonly used resource and memory leaks are commonly witnessed. Resource Acquisition Is Initialization (RAII) is an idiom that provides a protocol for acquiring and releasing resources.

Encapsulates Allocation and Deallocation

The classes that are written usually provide a level of abstraction over the physical resources available. RAII allows us to encapsulate the acquisition and release of these resources. A popular example is that of using a database connection. If the connection is acquired from the connection pool and not released back, it finally runs out of the connections and applications cannot continue working with the database. This is more probable if you leave this responsibility to the user of your class (another programmer). Here is an example in C++, that uses RAII to acquire the connection and release it:

class MyRecords
{
    private:
       DBConn connection;
	
    public:
       MyRecords()
       {
           connection = new DBConn();
       }
	
       ~MyRecords()
       {
           delete connection ;
       }
}

When this class is used, it guarantees release of the connection when its destructor is called. The destructor can be explicitly called, but it is automatically invoked if it is used as a local variable and goes out of scope. Your user now does not need to worry about the database connection, nor do you have to worry if he/she has released the database connection which can lead to undersirable situations.

void useMyRecords()
{
    // Allocated on stack
    MyRecords records;
	
    ....
	
    // Will run out of scope beyond this method
}

The same can be applied to any resource that a program might work with.

Gives Control To You

RAII is just half the story, it also includes releasing the resource. For your user, the two different steps of initializing your object and acquiring the resource has been combined into one, in fact completely encapuslated. What this also means is that your user does not have to worry in unavoidable circumstances like exceptions. Stack variables automatically go out of scope and their destructors are invoked.

It is not always necessary to acquire a resource in the constructor, it might be done in any other intermediate methods. In this case, care should be taken to check if the resource acquisition was successful before releasing it.

Lesser and cleaner code is just one of the post-effects, the real benefit is that you, as owner of your class, get complete control of the resources that your class uses. This is exponentially beneficial if you author a library or a framework.

Where is it applicable?

RAII needs to be supported by a language to be used. Generally, a language which uses non-deterministic garbage collection, lika Java does not support RAII. If the language supports use of custom-defined types for local variables (automatic objects in C++), you can take advantage of the automatic invocation of destructors when they go out of scope. It is also supported by object models and languages like COM which relies on reference-counted garbage collection.

More reading:

Tags: , , , ,

June 7, 2006

Two Exceptional Conversations on C++

Filed under: CPP

I had come across two exceptional conversations on C++ between two visionaries - Bill Venners and Bjarne Stroustrup. They are dated 2003, but are very much valid even today.

Titled as The C++ Style Sweet Spot and Modern C++ Style, the discussions answer some principle questions about moving from C to C++, using inhertiance the right way, using abstract classes for interface and considering the invariant for designing simple classes. If you haven’t read them yet, jump right ahead and consume them, they provide lot of food for thought and can act as design guidelines.

Unique thing about reading the discussions was that Stroustrup has not given just point answers, but has explained the reasons behind the thoughts. I am sure such reading can lead to best practices.

Tags: , ,

June 4, 2006

Why Binary Searches Can Break?

Filed under: commons

Binary searches and mergesorts can break, in fact, most of them will break because they follow the same method of calculating the mid-point for the search. It is usually calculated as average of low and high values. Here is what Josh Bloch says (the example uses Java):

The bug is in this line:

6: int mid =(low + high) / 2;

In Programming Pearls Bentley says that the analogous line “sets m to the average of l and u, truncated down to the nearest integer.” On the face of it, this assertion might appear correct, but it fails for large values of the int variables low and high. Specifically, it fails if the sum of low and high is greater than the maximum positive int value (231 - 1). The sum overflows to a negative value, and the value stays negative when divided by two. In C this causes an array index out of bounds with unpredictable results. In Java, it throws ArrayIndexOutOfBoundsException.

Very interesting, whatever the size of the integer, there will always be a condition when the sum of low and high will overflow it. Josh also gives some suggestions:

So what’s the best way to fix the bug? Here’s one way:

6: int mid = low + ((high - low) / 2);

Probably faster, and arguably as clear is:

6: int mid = (low + high) >>> 1;

In C and C++ (where you don’t have the >>> operator), you can do this:

6: mid = ((unsigned) (low + high)) >> 1;

A classic example where the code design can do the right or the wrong. It is important to realise that the code works in all the cases. While all is sometimes impossible to consider and we can use a subset, there is no guarantee that the subset will remain the same in future. That is why, in my opinion, as part of the maintenance of the application, the code should be verified against the new computing environment. Today, the software is re-released for change in business requirements or business environment, but it is also important to consider the changing computing environment.

Tags:

Creative Commons License Copyright © Abhijit Nadgouda. Hosted on Blogsome, powered by Wordpress