Tweakr 0.0.172 hits Maemo Extras!

Mar 10 2010 Published by Salvatore Iovene under Software

Tweakr has been finally pro­moted to Maemo Extras, check it out at http://maemo.org/downloads/product/Maemo5/tweakr/.

You can now eas­ily install it from the App. man­ager. I’ll write up a new tuto­r­ial some­day soon.

No responses yet

Tweakr 0.0.16

Feb 17 2010 Published by Salvatore Iovene under Software

Hi. I have released tweakr 0.0.16, which you should be able to install from Maemo Test­ing in a mat­ter of min­utes. A cou­ple of bugs fixed and the Silent pro­file hard­coded is what’s new. Update!

No responses yet

Tweakr promoted to extras-testing

Jan 24 2010 Published by Salvatore Iovene under Software

Hi, a quick update on Tweakr: it has now been pro­moted to extras-testing, since the reboot loop bug (thanks, hildon-home!) has been fixed.

Also a new fea­ture present: the Pro­file but­ton in the Sta­tus Menu gets replaced by Tweakr’s own but­ton (which looks iden­ti­cal), so that you won’t have get your Sta­tus Menu too crowded.

No responses yet

Introducing Tweakr

Dec 19 2009 Published by Salvatore Iovene under Software

I have been work­ing on a lit­tle util­ity pack­age for Maemo 5, called Tweakr. It’s a Settings applet that lets you tweak lit­tle known set­tings that could oth­er­wise be changed only by edit­ing con­fig­u­ra­tion files by hand.

It has a plu­gin archi­tec­ture, so you could write your own plu­gin too. The ones I have so far are Desktop and Hardware keys.

Desk­top

This plu­gin allows you to edit the labels of the book­mark short­cuts you have on your desktop.

Hard­ware keys

You can con­fig­ure the behav­ior of the Power Key, and whether uncov­er­ing the cam­era lens unlocks the device.

More plu­g­ins and fea­ture com­ing soon!

Here’s some screenshots:

Tweakr entry in the Settings

Tweakr

No responses yet

TABs vs Spaces. The end of the debate.

May 14 2007 Published by Salvatore Iovene under Software

When writ­ing source code, indent­ing is very impor­tant. Hav­ing a neat and clean pro­gram­ming style, let alone a pre­cise and uni­form one, is prob­a­bly one of the most impor­tant keys when attach­ing exam­ple source code with a job appli­ca­tion. I was myself asked to show some of my source code in my last two inter­views. Nobody ever asked me to show any run­ning pro­gram that I had made, though. Won­der why? A lot can be under­stood about the author just by glanc­ing quickly at some source code.

Indent­ing makes the source code eas­ier to read for us human beings, whereas the com­piler doesn’t really care (except for some lan­guages, where inden­ta­tion applies as a syn­tax ele­ment). Even if you’re not a pro­gram­mer, you can see the dif­fer­ences here:

Com­piler friendly

Compiler readable

Badly indented

Badly indented

Prop­erly indented

Properly indented

There is, I guess, no ques­tion that the last one, labelled as “Prop­erly indented”, is the most read­able. Prob­lem arise, though, when peo­ple start won­der­ing what they should use as indent­ing char­ac­ter. Some pre­fer TABs, other pre­fer blank spaces. A TAB, the key on the left of the Q of most Qwerty key­boards, is a sin­gle char­ac­ter that a text edi­tor can rep­re­sent what­ever way it wants. This is usu­ally cus­tomiz­able by the user, of course, so she can decide that a TAB will be shown as 8 spaces, or 4, or 2.

You can hear all the time some­one claim­ing, in turn, that TABs are evil or that spaces are evil, but the truth is that none is wrong, as long as you can indent.

I’ll use, as an exam­ple, a piece of source code taken from the ext3 mod­ule of the Linux ker­nel. The Linux pro­gram­ming guide­lines rec­om­mend using TABs for indent­ing, and that they should be 8 spaces wide. Let’s have a look at some code.

8-space TAB

8-space.jpg

4-space TAB

4-space.jpg

2-space TAB

2-space.jpg

As you can see, the orig­i­nal intent of the author, was to have the vari­able names aligned. But that align­ment gets screwed up as soon as a reader has a dif­fer­ent space-size for her TABs. What’s wrong there? Let’s use a very use­ful Vim tip: the :set list command.

:set list
set-list.jpg

This way, we can actu­ally see the TABs, as “>——-”. Of course there will be less dashes if part of the TAB area is occu­pied by some text. So, can you see what’s wrong with that? The author of that source code is using TABs not only for indent­ing, but also for align­ing! That way his align­ment gets messed up when some­body uses a dif­fer­ent TAB size. The solu­tion of this prob­lem is to sim­ply just use what ever you want for indent­ing, but use spaces for align­ing. Indent­ing must only be that left mar­gin that you give to some lines, but it’s not to be con­fused with align­ment. If the author of that source code had used TABs at the begin­ning of the lines, but just blank spaces between the type and the name of the vari­ables, his code would be as he meant it what­ever indent­ing style one’s edi­tor would use.

So, in the end, it doesn’t mat­ter whether you use TABs or space, for indent­ing, as long as you use just spaces for align­ing.

Use­ful Vim/Emacs tip

I like spaces, and add the fol­low­ing to the end of all of my source files:

/*
Local Variables:
mode:c++
c-basic-offset:2
c-file-offsets:((innamespace . 0)(inline-open . 0)(case-label . +))
c-tabs-mode:nil
End:
*/
// vim: filetype=cpp:expandtab:shiftwidth=2:tabstop=8:softtabstop=2

This way, if the reader uses Vim or Emacs (and maybe also gedit), her set­tings will be tem­porar­ily over­rid­den by mine, so, if she’s going to change my code, there are lit­tle chances that she’ll mess up my indenting.

The :set line options I use are the following:

set listchars=tab:>-,eol:$,trail:.,extends:#

It helps me to also spot trail­ing spaces. I rec­om­mend every­body to use the :set list, as it will pre­vent you to acci­den­tally mess up other’s indentation.

19 responses so far

How to improve the quality of programmers

Mar 09 2007 Published by Salvatore Iovene under Software

After claim­ing that most pro­gram­mers just can’t pro­gram, and actu­ally address­ing most of the prob­lems to the lack of pas­sion of peo­ple who decide to start a career as a pro­gram­mer, I would also like to express my point of view on a tightly related sub­ject: what can be done to improve the sit­u­a­tion? The prob­lem that I was try­ing to bring up in the spot­lights, is that a lot of peo­ple just start (or wish to start) a career in the IT for no par­tic­u­lar rea­sons. Those are the ones who don’t love and don’t loathe pro­gram­ming, and they just see it as some­thing that pays their bills. Well, maybe the first ques­tion that I should address, actu­ally is: why is this bad? Sure there are so many jobs which don’t require pas­sion at all, and peo­ple just do them because a job is just a job, and don’t really care. In my opin­ion, being a pro­gram­mer is different.

There are many peo­ple, espe­cially the ones who sit high in the hier­ar­chy of a com­pany, who see pro­gram­mers as the last and least impor­tant step of a lad­der. They often think that pro­gram­ming is quite of an auto­mated and repet­i­tive task, and it could basi­cally be done by any­one, with just a lit­tle train­ing. Unsur­pris­ingly, this seems to be the opin­ion of most com­mon peo­ple, who ignore what pro­gram­ming really is. I wouldn’t want to dis­crim­i­nate among dif­fer­ent types of pro­gram­ming, or dif­fer­ent pro­gram­ming lan­guages, but it’s obvi­ous to me that pro­gram­ming, to some extent, actu­ally can become an auto­mated an repet­i­tive task. That’s quite the minor­ity of cases, though, so I will sim­ply ignore them, and focus on the rest.

As any­body who’s a pro­gram­mer knows, pro­gram­ming is a highly cre­ative task, that requires good imag­i­na­tion and great prob­lem solv­ing skills. Every­body else might just see it as “typ­ing stuff on a com­puter”, and believe me, there’s a whole lot of edu­cated peo­ple who think that pro­gram­ming is a mon­key mat­ter. Hence the term “code mon­key”. This term has his­tor­i­cally been abused a lot, by even pro­gram­mers them­selves. A “code mon­key” is said to per­form a pro­gram­ming task so easy that even a mon­key could do, as the image sug­gests. There are two truths about this phe­nom­e­non: first of all, luck­ily, pro­gram­ming requires far more skills than it’s usu­ally believed; sec­ondly, and sadly, the major­ity of peo­ple just ignore it.

The prob­lem with lousy pro­gram­mer is kind of sim­i­lar to a medal: it’s dou­ble faced. You could actu­ally call it a dog try­ing to bite its own tail: as pro­gram­ming is believed to be an eas­ier and eas­ier task, more pro­gram­mers are needed; as more and more pro­gram­mers are needed, more peo­ple will jump on the field; as more and more peo­ple try to become pro­gram­mers, the lousier the aver­age qual­ity of pro­gram­mers gets. Unfor­tu­nately, what aver­age non-programming peo­ple miss to under­stand is that although it doesn’t really take a hard train­ing to become a lousy pro­gram­mer, it takes a damn hard one to excel in the art of pro­gram­ming. More­over, most peo­ple just lack the innate logic mech­a­nisms that make you a poten­tial pro­gram­mers. Such mech­a­nisms are devel­oped in your mind when you’re very young, and it’s quite rare to develop them after your twenty-somethings. With this, though, I’m not deny­ing that there are a lot of peo­ple who actu­ally do develop those mech­a­nisms in advanced age. I’m just try­ing to think of the big num­bers, here.

So, get­ting to the point, what went wrong and how can it be fixed? I don’t think it would be wise to say that what’s wrong is that there’s too much need of pro­gram­mers, ergo the aver­age qual­ity was inevitably doomed to lower and lower over the time. I rather think that the prob­lem is with edu­ca­tion. Of course I can’t speak for all the uni­ver­si­ties and col­leges in the world, but I can at least try and speak for the one I’ve known per­son­ally, or through peo­ple who have stud­ied there. It seems that, as more and more peo­ple apply to Com­puter Sci­ence or related depart­ments, the eas­ier it gets to get in (sorry for the pun), and to get through with it, i.e. to graduate.

I know this hap­pens most likely in any other fac­ul­ties, but see­ing that there are peo­ple who have been study­ing CS for three or more years, and still can’t get through the most sim­ple con­cepts, just doesn’t seem right to me. Yes­ter­day night, I was sit­ting in an IRC chan­nel about the C pro­gram­ming lan­guage, when some­body joined in and asked:

“I just started study­ing struc­tures in C, and I don’t get them. Can any­one explain to me what’s the use for them?”

Ok, I don’t really think there’s any­thing wrong in not get­ting the point of C struc­tures right away, but after a lit­tle chat­ting, it turned out that the guy was in his sec­ond year of Com­puter Sci­ence, and this was the sec­ond time he took the C class. Still that wouldn’t be a rea­son of hatred, of course (not that I have any hatred), but after another small while it turned out that the guy didn’t like pro­gram­ming at all, but he just got him­self into it because he applied to CS since he liked to “fid­dle around with com­put­ers”.

What’s really needed, in my opin­ion, is a harder and less tol­er­ant edu­ca­tional sys­tem, that would be more selec­tive, rather than push­ing every­one for­ward. Peo­ple that find out to be really not made for it, should just give up and move their focus on some­thing less.

I’m actu­ally very well aware that a lot of pro­gram­ming work, nowa­days, is not really rocket sci­ence, still this doesn’t mean that it should be done by com­pletely unqual­i­fied peo­ple. If what Jeff Atwood says in his post about pro­gram­mers who can’t pro­gram is true, and that is that 199 out of 200 appli­cants (not pro­gram­mers, appli­cants) can’t write any code what­so­ever, than it obvi­ously means that some­thing is wrong. Look­ing at the num­bers pro­vided by Joel Spol­sky, it looks like a lot of these basi­cally incom­pe­tent peo­ple are going to end up work­ing on an actual pro­gram­ming job, and maybe their code will end up on The Daily WTF (Paula, are you there?).

Unfor­tu­nately, the edu­ca­tion is not the only one to blame. No mat­ter how much edu­ca­tion will improve, there will always be unqual­i­fied peo­ple who are going to apply for jobs that require a lot of skills, and in the end the odds will help them, so they’ll man­age to get a job as a pro­gram­mer. Is it so bad, con­sid­er­ing that it’s most likely not going to be any crit­i­cal posi­tion, and the only ones that will be dam­aged will be the own­ers of the com­pany that hired them? Well, the point is that this is not true. There’s some­one else who gets dam­aged, in this sce­nario. I’m talk­ing about the com­mu­nity out there, the good pro­gram­mers, who find them­selves com­pet­ing with new­bies who’re happy to earn peanuts. The salaries keep going down, and cus­tomers are not able to dis­tin­guish a good job from a good one.

In a com­ment on the pre­vi­ous post of mine about this sub­ject, Hoowie Good­ell really gets a great point with this paragraph:

“There has been a great effort to indus­tri­al­ize pro­gram­ming, too. Again, there are many good fea­tures, and it’s a field I’m inter­ested in. Build­ing a large pro­gram requires a struc­tured approach. Lan­guage design, libraries, pro­gram­ming frame­works and IDEs can and should incor­po­rate as much exist­ing human knowl­edge as pos­si­ble: com­puter sci­ence, domain knowl­edge, solid pre-written code and human inter­face prin­ci­ples. (Check out Thomas Greene’s “Cog­ni­tive Dimen­sions of Nota­tions” for some of the lat­ter: I think of how pro­gram­ming tools fail to use them on a daily basis!)”

In a way, this sug­gests that the whole sys­tem is not ready yet, as it’s indeed years and years behind sev­eral other engi­neer­ing fields, and that’s a good rea­son, prob­a­bly, to explain why it’s so easy to fail at being a good pro­gram­mer. Let’s just try to get some insight­ful inspec­tion points, in order to build bet­ter gen­er­a­tion of programmers:

  1. Bet­ter edu­ca­tion.
    The whole higher edu­ca­tional sys­tem should be improved in sev­eral way. World­wide. Nowa­days, it looks to me that in many coun­tries grad­u­a­tion is just a direct con­se­quence of apply­ing to an Uni­ver­sity. Unfor­tu­nately, this kind of prob­lem must be addressed on a country-basis, to prop­erly iden­tify the spe­cific issues, but still the options that I would like to con­sider are worth men­tion­ing. It all comes down to a sin­gle point: there should be less tol­er­ance towards peo­ple that don’t learn. The thresh­olds for suc­ceed­ing in a course should be raised to greater dif­fi­culty. Cur­rent mod­els of test­ing should be seri­ously revised, so to ensure that stu­dents that really didn’t under­stand the sub­ject are not going to make it.
  2. Bet­ter tools.
    Are we try­ing to make pro­gram­ming just like a fac­tory chain or are we not? If we are, as it seems nowa­days, then the tools are not ready yet to sec­ond our inten­tions. Pro­gram­ming is too error prone and too time-consuming.
  3. Bet­ter process.
    Soft­ware process that doesn’t con­form to some stan­dards, say ISO-9000 (sorry if it’s inap­pro­pri­ate, I’m not an expert on this kind of stan­dards), shouldn’t be allowed to sell. Qual­ity insur­ance com­mit­tees should be taken more seri­ously as being part of the process. This might be against all prin­ci­ples of lib­er­al­ism, I know, as bad soft­ware, you may say, will not sell any­way. I know many bad soft­ware that did sell well, for greatly dif­fer­ent rea­sons than its (non) good quality.
  4. Bet­ter judg­ment when hir­ing.
    I’m not going to try to teach you how to run your com­pany, nor how to hire your crew. But some­times really crazy thing hap­pen (again, is Paula around?). A very inter­est­ing post by Joel Spol­sky (I’m sorry, I can’t find it any­more: does any­body know the link?) talks about only hir­ing “A”-people, where “A” means top class. If you’re ever hir­ing a “B”-person, he’s quite likely to hire a “C”-person, some­day. After that, it’s chaos. I rec­om­mend any­one not to lower their canons of per­fec­tions. Here’s another great arti­cle by Joel, about hir­ing good devel­op­ers, I rec­om­mend it.

Con­clud­ing, improv­ing the qual­ity of pro­gram­mers seems really to be a tough issue, and the whole thing depends on so many fac­tors that track­ing a pre­cise prob­lem is impos­si­ble. Cul­tural and tech­ni­cal dif­fi­cul­ties arise all the time, and get­ting clues is hard. I’ve tried to get around the prob­lem and give some insight­ful opin­ions: what do you peo­ple think?

11 responses so far

Why most programmers are lousy

Mar 08 2007 Published by Salvatore Iovene under Software

I’ve been in the IT field long enough to get to know many pro­gram­mers, both expe­ri­enced and just wanna­bies. Dur­ing this time, I’ve real­ized that most of them are just bad pro­gram­mers, sim­ply said. I find myself agree­ing with a bril­liant post by Jeff Atwood, which alleges that pro­gram­mers can’t pro­gram. What are the rea­sons for this? Many. Prob­a­bly, IMHO, the main fault has to be addressed to the lousy edu­ca­tion that peo­ple receive. But then again, the abil­ity of giv­ing edu­ca­tion remains directly pro­por­tional to the abil­ity of get­ting it, and where I see peo­ple com­plain­ing about low qual­ity of edu­ca­tion in Uni­ver­sity, I also see stu­dents with no inter­est in learn­ing. Let’s see some of the rea­sons why pro­gram­mers can’t really program.

  1. Young peo­ple study Com­puter Sci­ence just because it’s a trend. It sounds almost unbe­liev­able to me, but I must admit it’s mostly true. The vast major­ity of my old Uni­ver­sity mates just applied to the Com­puter Sci­ence depart­ment because… well: every­body was doing so. They fol­lowed the rest of the sheep.
  2. Young peo­ple study Com­puter Sci­ence because they wouldn’t know what else to do. That’s really another strong source of appli­ca­tions to Com­puter Sci­ence. A lot of young peo­ple in their teenage years just don’t know what they want to do as grownups. Com­puter Sci­ence still seems to be a good career oppor­tu­nity, so they just go for it.
  3. Young peo­ple study Com­puter Sci­ence because they think it’s a sure way of get­ting a job. 10-something years ago there was a big boom, and if you just knew some HTML, were thought to be a com­puter guru. These types of belief mark a deep foot­print on pop­u­lar say­ings, hence the wave of peo­ple apply­ing to Com­puter Sci­ence just because they can work, is still there.
  4. Many of today’s pro­gram­mers, were doing noth­ing else than surf­ing the net or using Word till last year. Espe­cially in small and ver­ti­cal based mar­kets, impro­vi­sa­tion just rules. Peo­ple learn some­thing, and lit­er­ally throw them­selves on the field. Draw­backs for qual­ity of their work are sim­ply inevitable. This is not only a group of illit­er­ate peo­ple that just jumped in to catch the big wave (what big wave, nowa­days?), but peo­ple with no pas­sion what­so­ever. In other words, I don’t think it’s pos­si­ble, nowa­days, to become a great pro­gram­mer if you didn’t start get­ting some inter­est in the field when you were very young, say about 10 years old (with the due excep­tions, of course).
  5. Many of today’s Com­puter Sci­ence stu­dents have no inter­est what­so­ever in what they’re force­fully study­ing. Just put together the pre­vi­ous items in this list and what do you get? A bunch of peo­ple who just don’t care, who want to get their piece of paper (the degree) as soon as pos­si­ble, and have absolutely no pas­sion in what they learn. That’s the worst. I strongly believe that pro­gram­ming is not just a job like many oth­ers, but you need pas­sion to get best at it.
  6. A lot of pro­gram­mers just don’t like to pro­gram. This goes for 100% of my ex Uni­ver­sity mates! Think of that: 100%. Of course it’s not the whole world but it makes a small statistics.
  7. A lot of pro­gram­mers just don’t get it. Not even the easy things. I was asked, few weeks ago, by a friend of mine who’s been study­ing Com­puter Sci­ence for now 4 years, what the dif­fer­ence is between a private and protected method in Java. Appar­ently read­ing the books isn’t enough any­more, nowa­days. Another guy asked me: “I’ve stud­ied point­ers in C, and I think I under­stood them. Still I can’t find any use for them… are they really used at all?”.
  8. Basi­cally all of the pro­gram­mers, or wannabe pro­gram­mers, men­tioned above, are miles away from the tech­ni­cal com­mu­nity. These peo­ple will totally ignore the exis­tence of:

    Slash­dot and sim­i­lar
    RSS
    Usenet
    IRC (“Is that like MSN?”)
    SVN and similar

As you can see, a really strong point, in my opin­ion, is the lack of care and pas­sion for the sub­ject of pro­gram­ming itself. Lousy pro­gram­mers are bound to pro­gram to take a wage home; good ones are bound to pro­gram for the sake of pro­gram­ming itself. Or course you can do that but still miss to be a good pro­gram­mer, but all falls down to numbers.

86 responses so far

How to write robust code

Jan 13 2007 Published by Salvatore Iovene under Software

As soft­ware is one of the most impor­tant issues in our era, writ­ing good robust pro­grams is essen­tial. This arti­cle is an in-depth essay focused on Object Ori­ented soft­ware and large projects. Every­thing said here, though, scales well to good direc­tives for small projects as well.

Our time is dom­i­nated by soft­ware. There is basi­cally soft­ware every­where around us; most of the object you can see right now around you, have some­thing to do with soft­ware, prob­a­bly because they were cre­ated using some sort of machine. Given the impor­tance of soft­ware nowa­days, I just have to find bugs unac­cept­able. Of course you might argue that a small and rare bug is a minor soft­ware won’t harm any­one, and is not nearly as impor­tant as a bug that could affect the soft­ware of an air­plane, and I’m going to agree with that. But as time goes by, every­thing has to be going towards per­fec­tion, and cur­rent trends about soft­ware seem to be going nowhere: there were bugs in soft­ware 30 years ago, and there are today. There was a time, in the begin­ning, where sci­en­tists thought that it would be rel­a­tively easy to write bug free pro­grams right away, but then they real­ized pretty soon that it wasn’t quite so. After all, soft­ware is writ­ten by us human beings, and we are doomed to make mis­takes or omis­sions. The point of this arti­cle is not that soft­ware should be always bug free, but that we, coders, should always get them to the min­i­mum, and here I’m going to present some ways to deal with pro­gram­ming in general.

One huge prob­lem, as I’ve faced quite often, is that as a pro­gram grows in size and depen­den­cies, its devel­op­ers start los­ing trace of its com­po­nents, get fur­ther away from the big pic­ture, and ease the intro­duc­tion of bugs. Note, I’m not talk­ing here about bugs caused by a sin­gle human error that can be labeled as a cheap error by any­one who would look at the code. I’m talk­ing about the sort of nasty bugs that nobody can spot right away with a glance at the code. I’m talk­ing about sys­tem wide bugs, usu­ally emerg­ing as a result of hardly related sub­sys­tems of the pro­gram. Usu­ally con­nec­tions between depen­den­cies and libraries.

Any­way, 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 com­mented
  • Well tested
  • It never segfaults

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

  • Exsten­si­ble
  • Reusable
  • Last­ing in time

Well designed.

Hav­ing already talked about this some­where else, I’ll be brief on this sec­tion. Writ­ing a com­plex pro­gram, a pro­gram made of hun­dreds of thou­sands lines of code, is a damn com­pli­cated thing: it takes many peo­ple and a lot of time. Usu­ally, the more peo­ple you involve in the project, the less robust code you’ll get in the end. Peo­ple will use dif­fer­ent con­ven­tions and dif­fer­ent styles. For this rea­son, not only it’s cru­cial to hire the right devel­op­ers, but it’s essen­tial to have a very strict and detailed spec­i­fi­ca­tion of the project. Pro­gram­ming is a cre­ative work, no doubt, and coders need to have free­dom so they can breathe. A con­strained coder is a chained coder, hence a dead coder and a threat to the qual­ity of the end prod­uct. But, in spite of how much we care for the free­dom and open­ness of ini­tia­tive from the devel­op­ers, we have to be aware that loos­ing con­trol means low­er­ing the qual­ity. A large project must be designed thor­oughly and care­fully, in every sin­gle details. Even though pro­gram­mers love free­dom, most of them also love exhaus­tive doc­u­men­ta­tion. If you want to make a good coder happy, and get the best out of him, flood him with docs and specs. Noth­ing pisses off the good coder as the lack of doc­u­men­ta­tion: it tears his moti­va­tion 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?”. Fur­ther­more, a project with­out good specs looks super­fi­cial, des­tined to fail­ure and with­out a future. A very good coder is hardly going to stay in a com­pany that doesn’t make good design for the projects. He will think that it’s a loser com­pany, and start look­ing around.

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

  • Exhaus­tive
  • Non redun­dant
  • Non con­tra­dic­tory
  • Easy to understand
  • Related 1:1 to the implementation

We want to cover every pos­si­ble out­come in our spec­i­fi­ca­tion, let be them exhaus­tive so that noth­ing will be left to case. We don’t want to repeat the same infor­ma­tion more than once, and be redun­dant for sev­eral rea­sons, e.g. infor­ma­tion should be retriev­able in exactly one place, and it would ease up con­tra­dic­tions. Doc­u­men­ta­tion should be for the devel­op­ers, i.e. writ­ten in the most straight­for­ward way for the right audi­ence: sim­plic­ity of lan­guage and straight­for­ward­ness of tables and schemes will spare some curses from the devel­op­ers. Fur­ther­more, as a spec­i­fi­ca­tion is just a way to put a pro­gram in words before it’s writ­ten, devel­op­ers should be eas­ily able to trans­late what they see on paper to code. Think about a shop­ping list: when I get one, I just go to the shop and take care of trans­lat­ing each item on the list to a phys­i­cal item in my shop­ping cart. Direct and easy.

Neat and tidy

A good def­i­n­i­tion of neat is: in a pleas­ingly orderly and clean con­di­tion. How does that apply to soft­ware? What is neat soft­ware? One nice word that I like in that def­i­n­i­tion is “pleas­ingly”. Neat soft­ware pleases the eye and the mind. Don’t want to be cocky here, but neat soft­ware is some­thing writ­ten by a good pro­gram­mer, and will be appre­ci­ated by another good pro­gram­mer. If some­body known as a good pro­gram­mer points at some soft­ware and says “That’s neat” and you find your­self look­ing at it and reply­ing “Huh? That’s just code”, I’m sorry but chances are that you are not a good pro­gram­mer. A good pro­gram­mer appre­ci­ates the beauty of some code, both on a small scale and on a large scale. Neat­ness of soft­ware on a small scale means that you’re able to look at one func­tion and appre­ci­ate the sim­plic­ity of it. Neat pieces of code are eas­ily read­able and use good name con­ven­tions. Please read this arti­cle 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 inte­gra­tion between com­po­nents and sub­sys­tem of a project. A bad inte­gra­tion would mean, e.g., hav­ing a project-wide global vari­able that points to a cer­tain sub­sys­tem, and using it every­where in the project. Or hav­ing two sub­sys­tems that, in a messed and inter­twined way, mutu­ally call each other’s meth­ods vio­lat­ing sev­eral lay­ers of abstrac­tion. Prov­ing what neat code is, turns up to be very dif­fi­cult. It’s a bit like the oppo­site of what hap­pens with com­mon 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 uni­corns or dragon don’t exist? You prob­a­bly agree that it’s much more dif­fi­cult. It’s just the oppo­site with neat code. I can show you bad code, and you will eas­ily agree that it’s bad. But look­ing at neat code doesn’t it prove it neat right away. It takes prob­a­bly years and years of expe­ri­ence, writ­ing a lot of code and read­ing a lot.

Well named

This topic has already been dis­cussed here, but repetuta juvant. As code is man­aged by pos­si­bly dozens or more peo­ple, being under­stood is an impor­tant key to increase robust­ness of the code. Writ­ing robust code also means writ­ing code that will eas­ily stay robust when other peo­ple will mod­ify of expand it, unless they have no clue, of course. The most your code is under­stood by oth­ers, the most likely they will not break your ideas, and keep the code robust. There are sev­eral ways of mak­ing own code eas­ily under­stood, and hav­ing a good, con­sis­tent and solid nam­ing con­ven­tion is one of them. Of course, as dis­cussed later, code needs to be well doc­u­mented also.

Well com­mented

I know, I know. Every­body says that you should com­ment your code. That’s what I say and that’s what I’ve been told. Still I’m now com­ment my own code enough as I should. Before you can then tell me “Who are you, then, to tell me to com­ment my code, if you don’t do it enough with yours?” let me remind you that we learn from mis­takes. What they don’t tell you about the impor­tance of com­ment­ing code, is some sub­tle and psy­cho­log­i­cal lit­tle thing. If you are a bad pro­gram­mer, you’ll never pro­duce good code. But if you are a good pro­gram­mer, some­times being in a hurry will make you pro­duce really bad code. There are two rea­sons why this can hap­pen: 1) you are in a hurry because you’re late with your dead­lines. With this, there’s noth­ing to do. 2) you are in a hurry because you’re just cod­ing fast, on the rush of some ideas that flashed you. In this case, com­ment­ing your code a lot will improve dras­ti­cally the qual­ity of your code. Always write your com­ments before writ­ing the actual code. This will make you real­ize it, if your func­tion is not really going to do what it’s sup­posed to do. Writ­ing the com­ment will also help you think more about what you’re doing, and being more con­scious about it. It will keep your state of mind clear and pre­cise. I strongly rec­om­mend using Doxy­gen to gen­er­ate a browseable HTML ver­sion of your com­ments, espe­cially if you’re writ­ing a library. Oth­er­wise, it’s still going to keep you on a pro­fes­sional 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 func­tion in your code, or each class, per­forms a spe­cific task in a cer­tain way, and noth­ing more. Given a cer­tain input, it will reli­ably return the same out­put. Right? You have to make sure of that, by writ­ing test cases. Test­ing the small­est units of your pro­gram doesn’t ensure that the whole is work­ing per­fectly, but helps. Pos­si­bly, append a hook to your Source Code Ver­sion­ing Sys­tem (SVN? Darcs?) so that the auto­matic test­ing suite will run auto­mat­i­cally on the server that hosts your repos­i­tory, before it accepts your patch. This is quite easy with Darcs.

It never segfaults

Of course this point applies to the lan­guages that allow seg­men­ta­tion fault, or Null­Point­erEx­cep­tion (in Java). It’s easy to get: if your code seg­faults, there are no excuses. No mat­ter how stu­pid the pro­vided input was, your pro­gram should not seg­fault. A good prac­tice, is that each and every function/method would check it’s argu­ment before doing any­thing. A solid excep­tion han­dling struc­ture is required. Again, you can object that I’m not really say­ing any­thing use­ful here: “Of course pro­grams shouldn’t seg­fault, I knew it!”, but think about it: it’s a mat­ter of atti­tude. You want to write a per­fect pro­gram, and there are some things you have to keep in mind. Be para­noid with seg­faults will implic­itly and secretly improve the gen­eral qual­ity of your code, with­out you even noticing.

Con­clu­sion

Writ­ing per­fect code is impos­si­ble. Espe­cially as the code grows in size and num­ber of pro­gram­mers. Achiev­ing the impos­si­ble, then, is beyond any good inten­tioned coder. What we can do, though, is just try to have the right atti­tude, which is about pre­ci­sion, care and, some­times, para­noia. Writ­ing com­plex pro­grams is not an easy thing, and, as such, should be han­dled with extreme care.

One response so far

Common mistakes when approaching OO design — Class dependencies

Dec 21 2006 Published by Salvatore Iovene under Software

Here we con­tinue with explain­ing some of the mis­takes com­monly made in Object Ori­ented design, and the good prac­tices that are often ignored. This arti­cle is focused on code main­tain­abil­ity and on improv­ing coöper­a­tion with peo­ple work­ing at the same project.

Encour­ag­ing class dependencies.

Hav­ing a lot of (mutual) depen­den­cies in the code is quite typ­i­cal of Spaghetti Code, and it’s def­i­nitely some­thing we want to avoid, in order to keep our design neat, improve main­tain­abil­ity and ensure ease of col­lab­o­ra­tion with col­leagues. What do I mean by “class depen­den­cies”? Let’s con­tinue the exam­ple from the last arti­cle, and sup­pose we have a cer­tain class GuiManager which, at some points, wants to gen­er­ate some reports. Let’s intro­duce now a cer­tain ReportManager, which is a class respon­si­ble for gen­er­at­ing 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 Report­Man­ager will have to look some­thing like this:

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

    private:
        TableReport m_tableReport;
        ChartReport m_chartReport;
};

There are sev­eral prob­lems in this imple­men­ta­tion. First of all, If the guy respon­si­ble 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 com­mit to the repos­i­tory, but this will break the ReportManager! So after a few hours, the guy respon­si­ble for the ReportManager checks out from the repos­i­tory, builds, and finds out that all the times he has used the TableReport need to be changed. Of course this is some­thing 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 prob­lems 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 lit­er­ally forc­ing the peo­ple who write TableReport and ChartReport to write a method named report(). So, this way we broke one depen­dency: the ReportManager doesn’t need to worry about the way every sin­gle report will call the method: it’s sure that a method named report() will exist.

There is, tho, another depen­dency. If some­body writes a new report, say XmlReport, this will need mod­i­fi­ca­tions to the ReportManager, because our logic so far implies that the ReportManager knows about all the reports. So, if we’re not the main­tain­ers of the ReportManager (because maybe it’s in some dif­fer­ent library, writ­ten by some­one else, and we don’t have access to the code), we will have to go ahead and ask the right­ful main­tainer to mod­ify the code. Hence, there’s an extra depen­dency, not struc­tural, this time, but log­i­cal. What if the main­tainer of the ReportManager gave us tools (read APIs) so that we can reg­is­ter our par­tic­u­lar report to the ReportManager? Con­sider the fol­low­ing 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 any­thing about any Report.

No responses yet

Common mistakes when approaching OO design

Dec 19 2006 Published by Salvatore Iovene under Software

Today I want to talk about Object Ori­ented prac­tices, and 3 com­monly made mis­takes. Very often, when review­ing code writ­ten by other peo­ple, I find vio­la­tions of com­mon OO prac­tices, that make the code a lot less main­tain­able. Here fol­lows a list of the most com­mon ones, and, of course, some expla­na­tions about them.

Layer vio­la­tion.

While not the most com­mon, this appears to me as the most dan­ger­ous. What is layer vio­la­tion? Let’s show it with an exam­ple. Assume we have a GUI dri­ven appli­ca­tion that reads data from a data­base and shows the results on the dis­play. We might con­sider hav­ing some upper level Con­troller class, and man­agers for each com­po­nent, e.g. GuiManager, DbManager, ReportManager. Assume that the Controller class runs a loop, and in that loop we take care of refresh­ing 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 hor­ri­ble thing here, but the layer vio­la­tion hap­pens in this->guiManager().reportTable().update(…). Imag­ine the var­i­ous com­po­nents of this scheme as lay­ers on top of each other. We have the Controller, the GuiManager and a cer­tain ReportTable.

What we’re doing, is access­ing the ReportTable layer from the Controller one. Why is this bad? Hav­ing layer vio­la­tions will fill your code up with dis­tur­bance. You will rapidly lose track of what does what (e.g., who is updat­ing the ReportTable? The Controller or the GuiManager?), and this will end up into an inter­twined mess com­monly known as Spaghetti Code.
Doing that, you are per­form­ing 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? Hav­ing classes access inner func­tion­ing of other classes will lead you to messy code, espe­cially when there’s more than one peo­ple work­ing on a project, as dis­cussed later in this arti­cle. Hav­ing all the com­mu­ni­ca­tion hap­pen­ing between adja­cent lay­ers will help us keep­ing the project con­sis­tent even in case of changes to com­po­nents. Imag­ine if one day I will decide that the GuiManager doesn’t need a ReportTable, but a ReportChart. My ideal sce­nario is the one where all the changes I need to make are only within the GuiManager. But if there was a layer vio­la­tion, such as the men­tioned one, I would have to mod­ify the Controller as well. When peo­ple in a group work on dif­fer­ent com­po­nents of a sys­tem, they don’t want to make a change that will break every­thing else. In order to avoid bro­ken code, it would be a good prac­tice to keep lay­ers comm­ni­cate with the adja­cent ones, accord­ing to well known interfaces.

Infor­ma­tion hiding.

This brings us to our next point. What does the Controller need to know about the mem­bers of the GuiManager? Ide­ally, noth­ing. Ide­ally, there would be no get­ters or set­ters, since the Controller doesn’t need to know any­thing about the GuiManager’s inner func­tion­ing. What needs to be done, in fact, is design­ing a well known inter­face for the GuiManager that the Controller can use. Once designed, such inter­face should never be changed, in order to ensure max­i­mum com­pat­i­bil­ity within the com­po­nents. Imag­ine you have just a cer­tain GuiManager::update() method, the Controller would just need to call this->guiManager().update() and, what­ever the GuiManager does, is none of the Controller’s busi­ness. Inside, the GuiManager might do some­thing like this->reportTable().update(), but in case this would change to a ReportChart, it wouldn’t break the Controller, and keep the peo­ple that work with it happy.

Abus­ing sin­gle­ton pattern.

Singletons are not a way to get your­self some global vari­ables. Think thor­oughly about the rea­sons why you really need a Singleton in your pro­gram. Is it just a way to access some vari­ables from every­where in the code? If the answer is yes, you should con­sider refac­tor­ing your code to get rid of the Singleton class. Keep also in mind that Singletons are ene­mies of unit test­ing. Have a Singleton class do some­thing, rather than con­tain some­thing. A typ­i­cal exam­ple of a class suit­able to be a Singleton is a Logger class. You need to access it from every­where in the code; the class doesn’t need to be aware of the appli­ca­tion it’s in; the class does (logs) and doesn’t just con­tain. If you write a Singleton class like the fol­low­ing, you’re doing some­thing wrong:

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

This class seems to have the sole pur­pose of eas­ing the access to a cer­tain username and password from every­where in the code, with­out the need of pass­ing them around. You should con­sider pass­ing ref­er­ences and data around only when needed, or adopt­ing some sig­nal­ing framework.

No responses yet

Next »