Wednesday, December 28, 2011

Software Quality

I do not regard myself as a software engineer. Sure, I 'do' programming (usually with some C-based language if you're interested), but such programming is to implement some functionality that I want or need for some purpose - to implement a model or a data processing tool for instance - which has been for my own use. As such, there has been minimal effort put into inherent extend-ability or modalarisation of my code. I've always paid relatively good attention to code commenting and some flexibility of use (personal, that is), but that mainly stems from my inability to remember implementational details rather than some grand vision of code reuse. I've also never really been bothered about efficiency or speed. I think this stems from the fact that when an undergrad, I did some programming with some fairly limited processors, on which resources (particularly memory) were limited and had to be at least considered, if not actively managed - moving from those things to a proper desktop led me to stop worrying about resources to the extent that I stopped even considering them. I would, and do, implement code in the way that it looked like it worked in my head, not in a way that would have been particularly efficient either in terms of computational resources or (my) time: another side-effect of the lack of memory on my part, I could look back on my code and almost reconstruct my line of thought. In summary, I was more a hacker than a crafter of code - it was more important what the stuff did and how it corresponded to the things swirling in my head, than how it looked on the screen, or how it actually worked. And I thought that this was all that was required, and was to be honest a little smug in thinking so.

Sometimes I feel that this is what programming actually is... Image from here.

However, in more recent times, my programming has had a number of additional constraints imposed. These are probably so fundamental to most normal people (by which I mean most programmers and software engineers), that me mentioning them may border on the ridiculous, but I think that they are probably not to your bog-standard academic-type, like me. It basically boils down to a simple fact: that there are other people out there, and that under certain circumstances, they might actually need to use/modify your code, or collaborate with you on this code. This process has only relatively recently begun to directly affect me and my work, since a little way into starting as part of the ALIZ-E project, but it's one that I am increasingly having to take into account, and one that I seemingly find myself a little reluctant to. Basically, I would say that the idea is that putting the effort into those aspects of software development that are not necessarily directly related to the desired functionality, but to more general infrastructure and usability from the perspective of the programmer (as well as the notional user of course), is very beneficial in the long run. Put like that, it seems sensible. But it's not particularly obvious when you're actually trying to throw together something that works in the face of a deadline. At least it didn't to me.

Anyway, this issue was raised in my mind over the past week or two for two reasons: firstly, I noticed that a project colleague has put up (or updated?) a page on his website about software quality; secondly, I just happen to be reading a book (given to me by some very dear friends) about programming (which is far more interesting than it may sound, but that is I think for another post when I've finished reading the book...).

This project colleague is Marc Schroder, and he is at DFKI in Germany, and this is the page I am referring to. The first time I met him was at the first ALIZ-E software integration meeting, at which he kept talking about good programming practice, and good practice regarding implementation structures and methods. To be perfectly honest, I viewed a lot of this as programming idealism, and distracting from the task at hand: implementing a (complex) system that would do what we wanted. Speaking to him during one of the meeting intervals, I made the point to him my opinion that a lot of academic programmers were hackers like me - good at making code that did what we wanted, but not necessarily good software engineers. I have no doubt that he'd heard and experienced this before, and indeed he was probably rather exasperated at the situation with the academic-hacker-types like me. He, on the other hand, has a good deal of experience with not just good quality programming, but also of multi-party project management, of which I had no experience. So, he knows what is involved in making some software actually work in a collaborative environment in which the participants are remotely interacting.

From the description on his software quality page page, and the various evangelist-style talks he's given us in the project on good coding practice (and I don't mean this in a negative manner - just descriptive of the style that academic-types speak to each other on subject matters that deeply interest them...), I have subsequently expanded my list of coding requirements. Or at least, I've added them to my desiderata, and am trying to actually incorporate them into the stuff I normally do. The order is roughly in importance for me at the moment, and misses things out (from Marc's list at least) probably because I don't (yet!?) understand their necessity.

  1. Error handling - as in properly, returning descriptions of what actually went wrong, so that you can figure it out, not just some way of not crashing the entire computer when something doesn't go to plan...
  2. Test-driven development - I think I understand the main principles involved, but to be honest, the practical details of how this actually should be approached are still tantalisingly out of reach... The idea of it being something like a living specification that keeps up to date with the code, is an actually useful tool in verifying updates, and replaces (to a certain extent) an external body of documentation, seems like a good idea all round.
  3. Refactoring - now this is something I have actually been doing for a while, though not for the efficiency aspects, but more for the matching of code operation to my internal cognitive machinations, and for some (limited) future flexibility (so I can easily change parameters and rerun for example)

I'd say that I now understand the necessity for these three things at least. And that I know that I need to apply it to my work as a fundamental feature rather than a mere after-thought. But I am also aware that this process has just begun for me, and that there is far more that I need to learn about testing regimes, interface definitions, etc, that are as yet just too unfamiliar to me. And yet there remains this vestigial resistance to such practice in favour of the hack-together-for-application methodology...

2 comments:

Rod Claar said...

Hi Paul,
As one who has taught hundreds of developers how to do TDD, the hurdle you face is about understanding that TDD is analysis. It provides the clear and testable understanding of what we are trying to code before we do it.
Hope this helps.

Rod Claar, CST
http://EffectiveAgileDev.com

Unknown said...

Hi Rod,

Thanks for your comment! I think that I do understand (at least partially - hence my comment regarding the 'living specification' in the sense that it provides a pre-specified framework for the progressive code implementation) that TDD is analysis.

The uncertainties I mentioned were more regarding the practical aspects of *how* to do this - at what level of abstraction/detail/granularity this testing regime should be applied to. I can imagine that too low a level of testing means a testing framework that could easily exceed that of the programme itself in length and complexity, whereas an incomplete or too highly abstracted testing regime may not be actually effective.

Much of this uncertainty is no doubt due to a lack of knowledge on my part, both of the standard procedures involved in TDD and of its relationship to my implementations.

In any case, thanks for your comment - I'll take a look at your site for some of the information I seek.

Paul