Archive for December, 2006

Darcs – The source code management system of the future?

Friday, December 29th, 2006

Having already mentioned some good practices for source code versioning and how important versioning is, in any case, I would like now to review and comment about what I find the best source code management system out there: darcs.

Darcs is a source control system written in Haskell (a functional language), and feature very solid mathematics bases, being completely engeneered on top of a “patch theory”. Not only darcs is straightforward and very easy to you, not only it’s very interactive and minimizes the chances of mistakes, but it also gives out features that the popular SVN doesn’t have. Here I’m going to show some use cases, and show how things are easier with darcs.

A brief start up

Before analyzing the key features, let’s have a brief start-up quick tutorial. The easiest way to get darcs, is to download a binary package. These packages contain a precompiled release of darcs, with everything needed statically linked inside. You only need o copy that somewhere in your $PATH, such as /usr/bin, /usr/local/bin, or whatever you have in your $PATH. Of course you can download the source code and build it yourself if you want.

Let’s now create a simple Hello World project, and use darcs to version it.

$ mkdir $HOME/projects/HelloWorld
$ cd !$
$ darcs init

darcs init will create all the files necessary to source-control the code. You will find a new directory named _darcs.

Now we can write our HelloWorld.cc main file:

#include <iostream>

using namespace std;

int main(void) {
    cout << "Hello World!"<< endl;
}

Time to add the file to version control.

$ darcs add HelloWorld.cc

Alright, now we really get into darcs. First of all, in case you didn’t notice, darcs doesn’t really need any server at the other end, like SVN would need an SVN server, or CVS would need a CVS server. This means no hassle in installing and configuring a server. Later we will see how darcs manages collaboration with remote users.

Now it’s time to save our changes to the repository.

$ darcs record
Darcs needs to know what name (conventionally an email
address) to use as the patch author, e.g. 'Fred Bloggs
<fred@bloggs.invalid>'.  If you provide one now it will
be stored in the file '_darcs/prefs/author' and used as a
default in the future.  To change your preferred author
address, simply delete or edit this file.

What is your email address?
Salvatore Iovene <salvatore@invalid.com>
addfile ./HelloWorld.cc
Shall I record this change?(1/?)[ynWsfqadjkc], or ? for help: y
hunk ./HelloWorld.cc 1
+#include <iostream>
+
+using namespace std;
+
+int main(void) {
+	cout << "Hello World!" << endl;
+	return 0;
+}
+
Shall I record this change?(2/?)[ynWsfqadjkc], or ? for help: y
What is the patch name? First record.
Do you want to add a long comment? [yn] n
Finished recording patch 'First record.'

Some points worth inspection here:

  • Why did darcs what to know my email address? That’s because everything you commit (they are named patches) will be known as coming from you. If you’re working with several people, darcs has to know who is committing what. Furthermore, people downloading your repository can, e.g. make some changes and improvements, and then issue a darcs send which will send you the patch via email, and you can evaluate it and decide if apply it.
  • What is a hunk? A hunkis a piece of a patch, i.e. a certain modification in some source file. If you have a large file, foo.c, and modify a certain function bar() at the beginning of the file, and then a certain other function tar() at the end of the file, this will result in two hunks. What’s the advantage of all this? Since darcs is so interactive, you may decide to either apply both hunks in the same pathc, so answer ‘y’ to both, or realize that they logically belong to two different patches, so you will say ‘y’ to one of them, and ‘n’ to the other. Then, after finishing recording the first patch, you issue a darcs record again, and record the other hunk in a separate patch, with a separate name, that forms a logical unit per se.

Now let’s make a small change.

#include <iostream>

int main(void) {
    std::cout << "Hello World!" << std::endl;
}

As you can see, we have removed the using namespace std; declaration, and added the std:: namespace prefix to cout and endl. A very important darcs command is whatsnew, that shows us how the code differs from the repository.

There are two hunks, as expected. Let's record the changes.

$ darcs record
hunk ./HelloWorld.cc 3
-using namespace std;
-
Shall I record this change?(1/?)[ynWsfqadjkc], or ? for help: y
hunk ./HelloWorld.cc 4
-	cout << "Hello World!" << endl;
+	std::cout << "Hello World!" << std::endl;
Shall I record this change?(2/?)[ynWsfqadjkc], or ? for help: y
What is the patch name? Removing the std namespace \
declaration.
Do you want to add a long comment? [yn]n
Finished recording patch 'Removing the std namespace
declaration.'

Obviously those two hunks must form one single patch, because we don’t want any patch to leave the repository in a broken state. Now we get to the cool stuff. Darcs lets you unrecord your changes, i.e. interactively rollout the patches until you are satisfied. We might change our mind about the last patch, and think that using namespace std; is not tha bad after all. No problem.

$ darcs unrecord

Fri Dec 29 12:53:32 EET 2006
Salvatore Iovene <salvatore@invalid.com>
* Removing the std namespace declaration.
Shall I unrecord this patch?(1/2)[ynWvpxqadjk], or ? for help: y

Fri Dec 29 12:37:33 EET 2006
Salvatore Iovene <salvatore@invalid.com>
* First record.
Shall I unrecord this patch?(2/2)[ynWvpxqadjk], or ? for help: n
Finished unrecording

Now there we are again, back as if nothing happened.

Imagine you want to have a copy of your repository, maybe on a different partition of your disk, or maybe on a USB storage drive:

$ cd ..
$ mkdir RepoCopy
$ cd RepoCopy/
$ darcs init
$ darcs pull ../HelloWorld/

Fri Dec 29 12:37:33 EET 2006
Salvatore Iovene <salvatore@invalid.com>
* First record.
Shall I pull this patch?(1/1)[ynWvpxqadjk], or ? for help: y
Finished pulling and applying.

Another directory is not the only way you can move your repository around, you can use SSH to copy it to another machine, and HTTP to fetch it. This is actually the way you handle collaboration. Imagine you have a server somewhere, named www.server.com, and there you want to have your central repository, with which you can collaborate with your development peers.

$ darcs push \
username@www.server.com:/var/www/htdocs/HelloWorld/repo

This will ask you which patches you want to push to that server, one by one, in the usual darcs interactive mode. I’m assuming that the directory /var/www/htdocs/HelloWorld/ on the server, hosts the http://www.server.com/HelloWorld/ website. Everybody can now get a copy of your project just by doing this:

$ darcs get http://www.server.com/HelloWorld/repo

And anybody with an account on that server, will be able to push patches, if they of course have write permission to the directory where the repository is.

Where to go from here

Here follow some must-read links if you’re interested in darcs. Probably in the future I will write more about it. Thanks for reading.

Getting a project done using clever design

Wednesday, December 27th, 2006

Sometimes, when coding a one-person-project at work or for fun, each one of us has found himself stuck at some point, and then the project eventually died out. Let’s have a look at some design and discipline recommendations that can help us achieving our goal.

Who doesn’t have a dream hidden in a drawer? Some of us coders have dreams about programs about which we’ve been thinking for a long time and perhaps never found the time to write. Now that we finally decide to settle down with it and write the thing down, we better not hurry. There are several complications that might arise during the creation of the project and most of them can be faced dealing with two issues: design and discipline. Let’s examine some of the possible issues.

Technical difficulties.

Not very unlikely, at some point of the development, we might find some obscure obstacles, impersonated by a very tough technical issue. I.e., we might think that it just can’t be done. Well sometimes it really can’t, but usually it’s a matter of technologies and the proper use of them. To address this kind of problem, there are basically two ways.

  1. Read up.

    Once you’ve determined what technologies you’re going to use, and what libraries, read up about them. “I’m going to learn them as I build up my project” is not a good strategy. You will probably realize that those are not the right technologies after all, or that you’re not using the right libraries. Or, most commonly, that you’re using your things in the wrong way. And that could be too late. This is a very common case of project failure. This is when you get to face an obstacle that seems insuperable, so you’ll waste a lot of time, and eventually get unmotivated. Start reading the websites of the technologies and libraries you want to involve, then read their documentation. You don’t need to read all the APIs of course, but at least you ought to read the technical overviews, the white papers and the general design perspectives. Possibly, buy a book about them and read it. Of course this will delay the start off of your project, but that’s better than investing 2 months in it and then have to trash everything. Typical case involve starting a new language, or a new framework. If you’re new to Hibernate don’t expect to just starting using it reading the Quick Start Tutorial. Most things, especially nowadays, aren’t just about using them. It’s mostly about understanding the big picture and knowing what the right angle from which approach them. The details will always come afterwards. Never ever underestimate the importance and the power of a good book on a certain matter. After having read up enough, you’re ready to start thinking about your application.

  2. Design.

    Never fail or omit to design your application (thoroughly) before hands. It might seem silly for small applications, but it never is. Draw down a scheme of the main components of the system, and remember: always divide and conquer. Start by drawing off a very big picture of the system. Ask yourself what components are involved, what technologies you’re going to use, what libraries you’re going to integrate. Once you have a clear and state-of-the-art idea of what the big picture is, you can start adding details. You can plan your database, for instance. Start that by individuating what the main components are, and how they interact with each other. Then you’re ready to design the database in more detail, i.e. specifying each field and relation. That will also help you entering more detail into the big picture of your application design. Start now considering all the components and their interactions. Define the objects you need and the way they communicate. Draw models and objects, possibly using UML. Be very careful and see to it that your model makes sense. Glitches and problems might (and should) already come up at this point. If your application takes less than 6-12 hours to be designed, than it’s either very simple, or you’re being superficial. Of course if we’re talking about Hello World, then you don’t need that much design, but this should be clear already!

If you’ve taken care of all this, the odds are with you and there are very little chances of failing for technical issues. Now it should just be about writing the actual code and you already know that it can be done, because you read up and designed the thing properly.

Scattered code.

Although Spaghetti Code was The Way, some long time ago, Object Oriented Programming has now been out there long enough so that we all should be able to write decent Object Oriented code. Seriously, if you’re still writing procedural Spaghetti Code, you should really read some Object Oriented Programming books and start living in the present. If you don’t even know what Spaghetti Code is, chances are that it’s what you do, so Google it up. Having well structured, layered and maintainable code will help you write less code, write better code, and finish your project sooner. This should come out automatically from a good design, but it’s worth spending some words. The more you are able to do the following, the better your project will go on: write a class, double-check it, test it, never touch it again. This is the divide and conquer paradigm. Once you have some parts of your project that are actually finished, you will find a lot more motivation in continuing. Having to continuously modify parts of your code, going back and forth on those changes again and again, is not only frustrating, but damaging the very structure of your project. I’m sure you have run through more that one session of “refactoring” your code. Moving pieces around, redesign classes, putting order, etc. This means that you’re wasting time that you could’ve used on adding new features or getting close to something that’s releasable.

Lack of deadlines.

Even if you’re working alone on an hobby project, set yourself deadlines and a roadmap. Reserve yourself some time each day in which you can work at your project. If you already know what version 0.3 will have, and what version 0.4 will look like, it’s more likely that you will stick to that. Give yourself small objectives and follow them, one after the other. Don’t push yourself too much, though.

Lack of professionalism.

This is a very important point, even though you may think it’s not. Even if you’re working all by yourself, whether it is a work project or a hobby one, always be professional. Remember the following rules.

  • Use a source versioning system.

    I don’t care if it’s CVS, SVN, Darcs, GIT or one of the many out there. Use one. Commit your work and keep track of the changes. This will not only help you not lose important code, and keep your work traced down correctly: it will also give you discipline and motivation. Read some best practices for SVN and other versioning systems.

  • Use a bug tracker.

    There’s a vast choice: bugzilla, trac and the Bug Genie are only few of them. Bug tracking is terribly important. Maybe not in the very initial phase of your project, but as it becomes usable, bug tracking can’t be neglected. Even if you’re working alone. Track the bugs scrupulously and like you were working on the most important project of the World. Bugs tend to be forgotten of after few hours. Few days in the best case. This is also something that will keep you motivated. Acting professionally.

  • Keep a website and build up a community.

    I assume that your project would be interesting to someone. The most motivating thing ever, is receiving encouragement and feedback from strangers. Keep a website of your project and let the community know what’s going on. Release it as soon as it’s ready and you’ll get feedback, eventually help. This is really highly motivating.

Lack of discipline.

Another big hit for unfinished projects. Stay away from it for more than 1 months, and it’s over. Most of the times. After one month, you will have forgotten a lot of things about it, and just can’t get the focus again. Just can’t find your way through it again. The more the time goes by, the more you’ll get detached from it, and it will eventually end up in the well of the forgotten and unfinished projects. To find the right discipline, force yourself to keep an eye on it at least two times a week, for 2 hours each time. Of course, this depends highly on how much you care about finishing your project, but of course we’re discussing this assuming that you care a lot.

Keep all of these hints in mind, and with a good dose of determination you can accomplish everything.

Common mistakes when approaching OO design – Class dependencies

Thursday, December 21st, 2006

Here we continue with explaining some of the mistakes commonly made in Object Oriented design, and the good practices that are often ignored. This article is focused on code maintainability and on improving cooperation with people working at the same project.

Encouraging class dependencies.

Having a lot of (mutual) dependencies in the code is quite typical of Spaghetti Code, and it’s definitely something we want to avoid, in order to keep our design neat, improve maintainability and ensure ease of collaboration with colleagues. What do I mean by “class dependencies”? Let’s continue the example from the last article, and suppose we have a certain class GuiManager which, at some points, wants to generate some reports. Let’s introduce now a certain ReportManager, which is a class responsible for generating reports. We have two types of report: TableReport, and ChartReport. They look like this:

class TableReport {
    public:
        void report()  {
            // do something
        }
};

class ChartReport {
    public:
        void report()  {
            // do something
        }
};

This means that the ReportManager will have to look something like this:

class ReportManager {
    public:
        void reportAll() {
            m_tableReport.report();
            m_chartReport.report();
        }

    private:
        TableReport m_tableReport;
        ChartReport m_chartReport;
};

There are several problems in this implementation. First of all, If the guy responsible for the TableReport one day wakes up, and decides that the method report() should rather be named generate(), he will not only be allowed to just change that and commit to the repository, but this will break the ReportManager! So after a few hours, the guy responsible for the ReportManager checks out from the repository, builds, and finds out that all the times he has used the TableReport need to be changed. Of course this is something we don’t want to happen.

The usual approach to this, is using an Abstract Base Class (ABC), which is a very robust way to sort out problems like this. Let’s see come code:

class Report {
    public:
        virtual void report() = 0;
};

class TableReport : public Report {
    public:
        void report()  {
            // do something
        }
};

class ChartReport : public Report {
    public:
        void report()  {
            // do something
        }
};

Report is our ABC, and with it we are literally forcing the people who write TableReport and ChartReport to write a method named report(). So, this way we broke one dependency: the ReportManager doesn’t need to worry about the way every single report will call the method: it’s sure that a method named report() will exist.

There is, tho, another dependency. If somebody writes a new report, say XmlReport, this will need modifications to the ReportManager, because our logic so far implies that the ReportManager knows about all the reports. So, if we’re not the maintainers of the ReportManager (because maybe it’s in some different library, written by someone else, and we don’t have access to the code), we will have to go ahead and ask the rightful maintainer to modify the code. Hence, there’s an extra dependency, not structural, this time, but logical. What if the maintainer of the ReportManager gave us tools (read APIs) so that we can register our particular report to the ReportManager? Consider the following code:

class ReportManager {
    public:
        void registerReport(Report const & r) {
            m_reports.push_back(r);
        }

        void reportAll() {
            std::list::const_iterator iter;
            for(iter = m_reports.begin();
                 iter != m_reports.end();
                 ++iter)
            {
                iter->report();
            }
        }

        private:
            std::list m_reports;
};

This way, the ReportManager doesn’t have to know anything about any Report.

Common mistakes when approaching OO design

Tuesday, December 19th, 2006

Today I want to talk about Object Oriented practices, and 3 commonly made mistakes. Very often, when reviewing code written by other people, I find violations of common OO practices, that make the code a lot less maintainable. Here follows a list of the most common ones, and, of course, some explanations about them.

Layer violation.

While not the most common, this appears to me as the most dangerous. What is layer violation? Let’s show it with an example. Assume we have a GUI driven application that reads data from a database and shows the results on the display. We might consider having some upper level Controller class, and managers for each component, e.g. GuiManager, DbManager, ReportManager. Assume that the Controller class runs a loop, and in that loop we take care of refreshing the GUI. What I’m going to write now is really wrong:

this->guiManager().reportTable().update(this->reportManager().populate(
    this->dbManager().query(someSqlString)));

Well, there are many horrible thing here, but the layer violation happens in this->guiManager().reportTable().update(…). Imagine the various components of this scheme as layers on top of each other. We have the Controller, the GuiManager and a certain ReportTable.

What we’re doing, is accessing the ReportTable layer from the Controller one. Why is this bad? Having layer violations will fill your code up with disturbance. You will rapidly lose track of what does what (e.g., who is updating the ReportTable? The Controller or the GuiManager?), and this will end up into an intertwined mess commonly known as Spaghetti Code.
Doing that, you are performing actions from parts of the code to which those actions do not belong. Classes shouldn’t care about what other classes are, but only about what other classes do. Think about it: do you really want to let the Controller know that the GuiManager has a ReportTable, inside? Shouldn’t the Controller tell the GuiManager just what to do, rather than how to do it? Having classes access inner functioning of other classes will lead you to messy code, especially when there’s more than one people working on a project, as discussed later in this article. Having all the communication happening between adjacent layers will help us keeping the project consistent even in case of changes to components. Imagine if one day I will decide that the GuiManager doesn’t need a ReportTable, but a ReportChart. My ideal scenario is the one where all the changes I need to make are only within the GuiManager. But if there was a layer violation, such as the mentioned one, I would have to modify the Controller as well. When people in a group work on different components of a system, they don’t want to make a change that will break everything else. In order to avoid broken code, it would be a good practice to keep layers commnicate with the adjacent ones, according to well known interfaces.

Information hiding.

This brings us to our next point. What does the Controller need to know about the members of the GuiManager? Ideally, nothing. Ideally, there would be no getters or setters, since the Controller doesn’t need to know anything about the GuiManager‘s inner functioning. What needs to be done, in fact, is designing a well known interface for the GuiManager that the Controller can use. Once designed, such interface should never be changed, in order to ensure maximum compatibility within the components. Imagine you have just a certain GuiManager::update() method, the Controller would just need to call this->guiManager().update() and, whatever the GuiManager does, is none of the Controller‘s business. Inside, the GuiManager might do something like this->reportTable().update(), but in case this would change to a ReportChart, it wouldn’t break the Controller, and keep the people that work with it happy.

Abusing singleton pattern.

Singletons are not a way to get yourself some global variables. Think thoroughly about the reasons why you really need a Singleton in your program. Is it just a way to access some variables from everywhere in the code? If the answer is yes, you should consider refactoring your code to get rid of the Singleton class. Keep also in mind that Singletons are enemies of unit testing. Have a Singleton class do something, rather than contain something. A typical example of a class suitable to be a Singleton is a Logger class. You need to access it from everywhere in the code; the class doesn’t need to be aware of the application it’s in; the class does (logs) and doesn’t just contain. If you write a Singleton class like the following, you’re doing something wrong:

class AccessData : public Singleton<AccessData> {
    friend class Singleton<AccessData>;
    public:
        std::string username;
        std::string password;
};

This class seems to have the sole purpose of easing the access to a certain username and password from everywhere in the code, without the need of passing them around. You should consider passing references and data around only when needed, or adopting some signaling framework.

5 SVN best practices

Friday, December 15th, 2006

Versioning systems like CVS, SVN or Darcs are very important tools, that no serious programmers can omit to use. If you started a project without using any versioning tools, I really recommend that you start using one immediately; but I’m not discussing this right now.

I would like to point your attention to some best practices that I recommend when working in a team.

  1. Don’t use versioning like it were a backup tool.

    I’ve heard this question too often: “Have you put your code safely on SVN?”. That’s a bad question. Storing code to an SVN server is not meant for safety, i.e. for fear of losing it. You are talking about something else, and that’s called backup. Take Darcs, a not so popular versioning system. It can start without a server, and you can just run it locally on your machine without launching any daemon whatsoever. A faulty hard drive can still make you lose all your work, of course. That’s why you have to do backups, of course, but they don’t have anything to do with versioning. Hence, committing to the repository once a day, before taking off home, e.g., is not an acceptable practice, especially if you work in a team. Doing that would be like making a daily backup. An SVN commit, instead, has to have a meaning of some sort, not just “Ok, let’s store to the SVN server the work of today”. Moreover, sometimes, if the schedule is tough and the cooperation is tight, you need to commit very often so your peer will keep up with you all the time, and not just find out, at evening, that he’s got dozens conflicts after checking out your code.

  2. Commit as soon as your changes makes a logical unit.

    How often should you commit? Theres no such thing as committing too often, or too rarely. You should commit each time your changes represent a logical unit, i.e. something that makes sense. Usually that happens because you’re following a plan, when coding (because you are, aren’t you?). So, you find out a bug in the trunk, plan a strategy about how to fix it, fix it, and then commit. This makes sense because that’s a commit that fixes a bug. So that revision X is buggy, while revision X+1 is not. Don’t be shy about committing too often. Should you just find an insignificant typo in a debug string, or in a comment, don’t be afraid of committing just to fix that. Nobody will be mad at you for being precise. Consider the extreme situation in which, after months and months, you may want to remember “What was the revision where I fixed that typo in that debug string?”. If you dedicated one signle commit for the actual finite logical unit of correcting the typo, you can just scroll back your changelog and find it. But what often happens, is that people will be doing something else, and, while doing that something else, will notice the type, and correct it, and basically merge that correction with the rest of the commit, making that thing losing visibility. To make it simple: your SVN comments shouldn’t explain that you did more than one thing. If your SVN comment looks like “Fixing bugs #1234 and #1235″ or “Fixing bug #4321 and correcting typo in debug sting” then you should’ve used two commits.

  3. Be precise and exhaustive in your commit comments.

    The second most annoying thing ever is committing with blank comments. If you’re working in a team, your peer developers will be frustrated about it and possibly mad at you, or will label you in a bad way; possibly publicly humiliate you. If you’re working alone, you will experience what you’re hypothetical development companions would have: frustration in not being able to easily track down what a certain commit did. Comments in commits are important. Please be precise and explain in detail everything you did. In the optimal case, I shouldn’t need to read your code.

  4. Never ever break the trunk.

    This is probably the most annoying thing when dealing with people who can’t use versioning. Breaking the trunk is an habit that will quickly earn you the hatred of your colleagues. Think about it: if you commit a patch that breaks the trunk, and then I check it out, what am I going to do? The project won’t build so I either have to fix it, or come to your desk and complain to you. In both cases I’m wasting some time. And consider the first case again: what should I do after fixing your broken code? Commit it? Sending you a diff? If I’ll commit, chances are that you’ll have conflicts when you checkout, and you’ll have to waste time in resolving them. Maybe sending you a patch would be the best way, but still it’s a waste of time for the both of us. So the thing is: before committing, ALWAYS double check! Make a clean build and make sure that it builds. And don’t forget to add files! It’s a very common mistake: committing good code, but forgetting to add a file. You won’t realize, because the thing builds, but when I’ll checkout, I’ll have troubles, because of missing file(s). If you’re using Darcs, just make a “darcs get” in a new directory, and then build.

  5. Branch only if needed.

    There are some ways to handle branches, but here’s my favorite. The most of the work should happen in the trunk, which is always sane, as stated by the previous practice, and the patches should always be small, so that they can be reviewed very easily. If you find yourself in the situation of needing to write a large patch, then you should branch it. In that way you can have small patches that will break your branch over the time, but they can be easily reviewed. After the process is completed, i.e. you’ve achieved your goal of fixing a bug or implementing a new feature, you can test the branch thoroughly, and then merge it to the trunk.

10 advice to write good code

Thursday, December 14th, 2006

Having been coding for 16 years now (I started quite young), I have seen a lot of bad code. Code is not good just because it works. So here’s a quick list of 10 advice that you’d better keep in mind while coding.

  1. Don’t sacrifice code maintainability to performance, unless it’s strictly necessary.

    This happens very often. You have to consider that your code is likely to be read by many persons, and some of them will read it after you might have parted from that company. Remember that you won’t remember what your own code does after few weeks. So always try to put things in the most readable and obvious form, even if this will require writing more lines of code, or having less performing code. Of course this is not so important if performance is your number one issue. Try, for instance, to avoid use of the ?: operator in C/C++. Everybody will understand it anyway, but a good old if statement will do it, so why not going for it?

  2. Be precise as a Swiss clock, when it comes to naming conventions.

    Nobody wants to read class names or variable names that look like gibberish. Don’t be mean on the keyboard: when you type, remember that somebody else will have to read it, so be extensive.

    1. Name your variable NumberOfItems rather than items_n. Don’t use cryptic prefixes to class name. Name your class ClientMessageOperationsBasicFunctor rather than CMOpFunctor. It’s a lot more typing for you, but a lot less hassle reading for the ones that will come after you.

    2. Don’t change your conventions. If you’re calling the iterators i, don’t call any of them n, ever. You will induce confusion to your reader. It doesn’t seem as important as it actually is. If you call a class ClientMessageBlockContact, then do not have ServerMessageContactBlock. Be perfect, be precise, be obsessed.

  3. Use a good and consistent indentation style.

    Never ever have more than one blank line. Don’t have trailing spaces at the end of the lines. Don’t have blank spaces or TAB characters in blank lines. A blank line must be blank, that is.Be consistent: don’t use TABs to indent in one file, and spaces in another one. Possibly, use 8-chars wide TABs to indent. If you find yourself going beyond 80 rows too often, then that could be an indication that there might be some design flaws in your program. Tweak your editor to show you the end-of-line character and the TABs.

  4. One class, one file.

    Don’t write files like ServerMessages.h where you write all the class that are ServerMessages. One class goes in one file. If you find yourself thinking that you can’t do it, review your design.

  5. In C/C++, project includes use “”, dependency includes use <>.

    If you’re including a file that’s local to your project, use #include "file.h"; if it’s an external dependency, do #include <file.h>. Why? I’ve seen people including <file.h> and then just put things like /usr/includes/my_project in the inclusions search path, so that nobody will be able to compile before installing. That’s a bad assumption. And you don’t want to end up in that error.

  6. Always compile with -ansi -pedantic -Wall -Werror flags (or similar, according to your compiler).

    Let’s adhere to standards. Let’s avoid warnings. A warning might become an error in the future.

  7. Use TODOs and FIXMEs.

    If you know that you, or somebody else, will have to return on a certain piece of code to add or modify some functionality, please mark it with a TODO. If you know that a piece of code is buggy but you can’t fix it right now, add a FIXME marker. Later on, it will be easy to grep the source tree for TODOs and FIXMEs and analyze them, especially if they’re very well commented.

  8. Comment your own code.

    Seriously: you’re going to forget, sooner than you think. Just invest 5% of your time in writing commented code. Never assume that code is self-explanatory, just write a couple of lines for everything you do. Comments are not only meant to generate doxygen documentation. You have to assume that somebody else will read your code and need to modify/extend it.

  9. Use a versioning system even if you’re working alone.

    Yes, versioning is not just for working in a team. Use Darcs or SVN even if you’re working alone: you won’t regret it.Commit often and try to be professional all the time. Later on somebody else might join you. Or then you might find useful to revert to previous versions of your program. And it will help you to keep trace of what you’re doing.

  10. Use a bug tracking system even if you’re working alone.

    Things like Bugzilla are EXTREMELY useful. Usually you will forget bout a bug after less than 2 days. Everytime you find a bug, either fix it immediately, or mark it to your personal bugzilla. And always fix bugs first, and then write new code.

Common errors:

  • It compiles, so it works.
  • It works here, so it works everywhere.
  • Commenting? We don’t have time to waste, we gotta ship!
  • UML diagrams are useless.
  • Plan code so that we can reuse it is useless: we’ll end up writing everything from scratch anyway.
  • Unit tests are a waste of time.