(Web) Standards actually do matter a lot

by Salvatore Iovene on 17 January 2007 — Posted in Web, Design, Articles

A week ago I stumbled upon this article from Stuart Brown, which actually even got a fair amount of Diggs. As soon as I read it, I felt obliged to reply extensively to it, as I think it mostly represent everything which is wrong in the current web design trends (or should I say all time web design trends?).

Something that really annoyed me about the article, was the lack of serious points and the abundance of useless words like “some standards evangelist”, “Obsessing over semantically correct markup”, “a few standards zealots”, “zealotry accomplishes nothing but a collection of smug faces and a collection of ‘XHTML 1.1 Compliant’ bylines”. Those were only fruitless diversions and not real arguments.

The authors gets one thing right, though, and it’s that

your users don’t care about XHTML, they care about how your site appears.

Alright, we all can agree that most of the average Internet users completely ignore everything about words like HTML, CSS, JavaScript, PHP and so on. We can’t, at these point blame the users: I don’t know anything about the inner workings of most of the things I use on a dally basis myself, so no big deal. In spite of this, serving the user is not quite equivalent to fooling him. Giving the user something that actually works, but whose inner workings are totally crippled, is absolutely wrong. The author of the mentioned article furthermore says:

If you can satisfy the usability needs of 100% of your users, yet your code doesn’t validate, then arguably you need do no more.

I’m really strong about my disagreement here. Validation serves a purpose: that is to minimize differences when rendering the website in different browsers. A well validated page doesn’t need any guess-based correction by the browser. And Stuart talks about usability, whereas a website that doesn’t validate will have a harder time in meeting usability requirements for impaired persons. On February 2006 there was a story about Target (a retailer), being sued because its pages were unaccessible by visually impaired users. The retailer was accused of violating the California Unruh Civil Rights Act, the California Disabled Persons Act and the Americans with Disabilities Act. Needless to say, the website still doesn’t validate (it doesn’t even have a DOCTYPE).

So, why else standards (and especially web standards) are needed?

  1. Standards make it easier for your browsers to render the pages.

    HTML or CSS are, in a way, standards. I.e. a set of rule, meant as a markup language specification, to be followed in order to design a web page. On top of these specifications, people who write browsers have done their work. Unfortunately, though, not all developers are able to, or care to, be strict regarding standards. That means that the browsers must have a way to correctly interpret some code even though it’s fundamentally incorrect. What’s the result of this? Browsers developers have to waste time into taking care of correcting the mistakes of web developers. This, in turn, gives web developers the chance to relax and write worse and worse code. And this makes browsers developers’ life worse, and their work slower. In the end the users get nothing but worse and worse products.

  2. Standards make life easier for users.

    We can take this off the Web Standards examples, and move to some “real life” cases. Ironically enough, the other day I was staring at my toilet seat for a while, and noticed that the holes in the toilet in which you can screw your seat in, are at a fixed distance, and just slightly larger than longer, so to give a little margin: i.e. if you want to buy a new toilet seat, the distance between the screws with which you attach it to the toilet must be between X and X+1 cm. So, when I went to the shop to get a new toilet seat, I didn’t have to worry about the size. Vendors of toilets and vendors of seat had just agreed on a standard size. The result? No hassle for the user (me).

  3. Search engines like standards.

    Search engines don’t like finding errors. If they have trouble parsing your pages, they may not get to your carefully chosen keywords, won’t be able to find all those tightly focused meta tags. Your site will be crippled on any search engine results page. This is not good. A well designed website creates a clear channel, a road map, for search engines, so they know to go exactly where you want them to go and see exactly what you want them to see.

End of the list? Yes. This is all that matters, in the end, to the final user. He doesn’t care how, but in the end he gets better products. Of course there are lots of side effects, e.g.:

  • Standards minimize the differences in the way your pages appear in different browsers.
  • Standards improve the quality of your code, hence the quality of your product.
  • Code that adheres to standards is easier to maintain.
  • Validating your code during the development process eases the discovery of flaws and mistakes.
  • Standards increase your value.

Before anyone could say that nobody needs a new article about web standards, let me remind you that the following websites won’t validate:

This means that the standards-aware developer are just a tiny minority. The rest, obviously, don’t think that quality is a good asset for their websites. Writing non-validating code is a big step backwards, on the path of perfection.

Bibliography


Get new articles via email

Related posts:

How to write robust code

by Salvatore Iovene on 13 January 2007 — Posted in Coding, Design, Articles

As software is one of the most important issues in our era, writing good robust programs is essential. This article is an in-depth essay focused on Object Oriented software and large projects. Everything said here, though, scales well to good directives for small projects as well.

Our time is dominated by software. There is basically software everywhere around us; most of the object you can see right now around you, have something to do with software, probably because they were created using some sort of machine. Given the importance of software nowadays, I just have to find bugs unacceptable. Of course you might argue that a small and rare bug is a minor software won’t harm anyone, and is not nearly as important as a bug that could affect the software of an airplane, and I’m going to agree with that. But as time goes by, everything has to be going towards perfection, and current trends about software seem to be going nowhere: there were bugs in software 30 years ago, and there are today. There was a time, in the beginning, where scientists thought that it would be relatively easy to write bug free programs right away, but then they realized pretty soon that it wasn’t quite so. After all, software is written by us human beings, and we are doomed to make mistakes or omissions. The point of this article is not that software should be always bug free, but that we, coders, should always get them to the minimum, and here I’m going to present some ways to deal with programming in general.

One huge problem, as I’ve faced quite often, is that as a program grows in size and dependencies, its developers start losing trace of its components, get further away from the big picture, and ease the introduction of bugs. Note, I’m not talking here about bugs caused by a single human error that can be labeled as a cheap error by anyone who would look at the code. I’m talking about the sort of nasty bugs that nobody can spot right away with a glance at the code. I’m talking about system wide bugs, usually emerging as a result of hardly related subsystems of the program. Usually connections between dependencies and libraries.

Anyway, the path to write bug free code, is the one you step when you write robust code. What do I mean by that? Robust code has some features:

  • Well designed
  • Neat and tidy
  • Well named
  • Well commented
  • Well tested
  • It never segfaults

As a result of some of these, robust code is also:

  • Exstensible
  • Reusable
  • Lasting in time

Well designed.

Having already talked about this somewhere else, I’ll be brief on this section. Writing a complex program, a program made of hundreds of thousands lines of code, is a damn complicated thing: it takes many people and a lot of time. Usually, the more people you involve in the project, the less robust code you’ll get in the end. People will use different conventions and different styles. For this reason, not only it’s crucial to hire the right developers, but it’s essential to have a very strict and detailed specification of the project. Programming is a creative work, no doubt, and coders need to have freedom so they can breathe. A constrained coder is a chained coder, hence a dead coder and a threat to the quality of the end product. But, in spite of how much we care for the freedom and openness of initiative from the developers, we have to be aware that loosing control means lowering the quality. A large project must be designed thoroughly and carefully, in every single details. Even though programmers love freedom, most of them also love exhaustive documentation. If you want to make a good coder happy, and get the best out of him, flood him with docs and specs. Nothing pisses off the good coder as the lack of documentation: it tears his motivation apart. “Why should I start to read their minds and run by guesses” - he thinks, “when they didn’t even get the time to write good specs?”. Furthermore, a project without good specs looks superficial, destined to failure and without a future. A very good coder is hardly going to stay in a company that doesn’t make good design for the projects. He will think that it’s a loser company, and start looking around.

But what does good design mean? A good design is:

  • Exhaustive
  • Non redundant
  • Non contradictory
  • Easy to understand
  • Related 1:1 to the implementation

We want to cover every possible outcome in our specification, let be them exhaustive so that nothing will be left to case. We don’t want to repeat the same information more than once, and be redundant for several reasons, e.g. information should be retrievable in exactly one place, and it would ease up contradictions. Documentation should be for the developers, i.e. written in the most straightforward way for the right audience: simplicity of language and straightforwardness of tables and schemes will spare some curses from the developers. Furthermore, as a specification is just a way to put a program in words before it’s written, developers should be easily able to translate what they see on paper to code. Think about a shopping list: when I get one, I just go to the shop and take care of translating each item on the list to a physical item in my shopping cart. Direct and easy.

Neat and tidy

A good definition of neat is: in a pleasingly orderly and clean condition. How does that apply to software? What is neat software? One nice word that I like in that definition is “pleasingly”. Neat software pleases the eye and the mind. Don’t want to be cocky here, but neat software is something written by a good programmer, and will be appreciated by another good programmer. If somebody known as a good programmer points at some software and says “That’s neat” and you find yourself looking at it and replying “Huh? That’s just code”, I’m sorry but chances are that you are not a good programmer. A good programmer appreciates the beauty of some code, both on a small scale and on a large scale. Neatness of software on a small scale means that you’re able to look at one function and appreciate the simplicity of it. Neat pieces of code are easily readable and use good name conventions. Please read this article if you want to know more about good code on a small scale. Neat code on a larger scale, on the other hand, means neat integration between components and subsystem of a project. A bad integration would mean, e.g., having a project-wide global variable that points to a certain subsystem, and using it everywhere in the project. Or having two subsystems that, in a messed and intertwined way, mutually call each other’s methods violating several layers of abstraction. Proving what neat code is, turns up to be very difficult. It’s a bit like the opposite of what happens with common logic: if I want to prove you that, say, lions exist, I can just go to Africa, pick one and show it to you, then say “That’s a lion, ergo lions exist”. But how can I prove that unicorns or dragon don’t exist? You probably agree that it’s much more difficult. It’s just the opposite with neat code. I can show you bad code, and you will easily agree that it’s bad. But looking at neat code doesn’t it prove it neat right away. It takes probably years and years of experience, writing a lot of code and reading a lot.

Well named

This topic has already been discussed here, but repetuta juvant. As code is managed by possibly dozens or more people, being understood is an important key to increase robustness of the code. Writing robust code also means writing code that will easily stay robust when other people will modify of expand it, unless they have no clue, of course. The most your code is understood by others, the most likely they will not break your ideas, and keep the code robust. There are several ways of making own code easily understood, and having a good, consistent and solid naming convention is one of them. Of course, as discussed later, code needs to be well documented also.

Well commented

I know, I know. Everybody says that you should comment your code. That’s what I say and that’s what I’ve been told. Still I’m now comment my own code enough as I should. Before you can then tell me “Who are you, then, to tell me to comment my code, if you don’t do it enough with yours?” let me remind you that we learn from mistakes. What they don’t tell you about the importance of commenting code, is some subtle and psychological little thing. If you are a bad programmer, you’ll never produce good code. But if you are a good programmer, sometimes being in a hurry will make you produce really bad code. There are two reasons why this can happen: 1) you are in a hurry because you’re late with your deadlines. With this, there’s nothing to do. 2) you are in a hurry because you’re just coding fast, on the rush of some ideas that flashed you. In this case, commenting your code a lot will improve drastically the quality of your code. Always write your comments before writing the actual code. This will make you realize it, if your function is not really going to do what it’s supposed to do. Writing the comment will also help you think more about what you’re doing, and being more conscious about it. It will keep your state of mind clear and precise. I strongly recommend using Doxygen to generate a browseable HTML version of your comments, especially if you’re writing a library. Otherwise, it’s still going to keep you on a professional line, which is always a good thing.

Well tested

Write and use unit tests. If your code is well designed, there are good chances that each function in your code, or each class, performs a specific task in a certain way, and nothing more. Given a certain input, it will reliably return the same output. Right? You have to make sure of that, by writing test cases. Testing the smallest units of your program doesn’t ensure that the whole is working perfectly, but helps. Possibly, append a hook to your Source Code Versioning System (SVN? Darcs?) so that the automatic testing suite will run automatically on the server that hosts your repository, before it accepts your patch. This is quite easy with Darcs.

It never segfaults

Of course this point applies to the languages that allow segmentation fault, or NullPointerException (in Java). It’s easy to get: if your code segfaults, there are no excuses. No matter how stupid the provided input was, your program should not segfault. A good practice, is that each and every function/method would check it’s argument before doing anything. A solid exception handling structure is required. Again, you can object that I’m not really saying anything useful here: “Of course programs shouldn’t segfault, I knew it!”, but think about it: it’s a matter of attitude. You want to write a perfect program, and there are some things you have to keep in mind. Be paranoid with segfaults will implicitly and secretly improve the general quality of your code, without you even noticing.

Conclusion

Writing perfect code is impossible. Especially as the code grows in size and number of programmers. Achieving the impossible, then, is beyond any good intentioned coder. What we can do, though, is just try to have the right attitude, which is about precision, care and, sometimes, paranoia. Writing complex programs is not an easy thing, and, as such, should be handled with extreme care.


Get new articles via email

Related posts:

Getting a project done using clever design

by Salvatore Iovene on 27 December 2006 — Posted in Design, Articles

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.


Get new articles via email

Related posts:

Common mistakes when approaching OO design - Class dependencies

by Salvatore Iovene on 21 December 2006 — Posted in Coding, Design, Articles

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.


Get new articles via email

Related posts:

Common mistakes when approaching OO design

by Salvatore Iovene on 19 December 2006 — Posted in Coding, Design, Articles

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.



Get new articles via email

Related posts:

10 advice to write good code

by Salvatore Iovene on 14 December 2006 — Posted in Coding, Design, Articles

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.



Get new articles via email

Related posts: