Just A Summary

Piers Cawley Practices Punditry

Testing Your Assumptions

Posted by Piers Cawley Sun, 04 Dec 2005 15:37:00 GMT

One of the joys of writing applications using Ruby on Rails is the way the framework is constantly evolving better ways of doing stuff. It’s one of the dangers too.

Each release of Rails brings new and groovy features to the table, so it’s nice to stay close to the edge. However, when you do that, a change in the framework can bring your whole app crashing down because a key assumption you made turns out not to be true any more.

This is especially common when the assumed behaviour is undocumented, or a surprising consequence of behaviour that is documented.

When this happens, your test suite can have failures everywhere; it’s hard to work out precisely what the underlying problem is.

So, what to do?

Easy. Write tests that express your assumptions. It’s always good to make assumptions explicit. It’s better still to make them executable. Whenever you use something that’s a little bit surprising or hard to find in the docs, or when you do something that works around a bug, write a test.

Then, when the framework changes and tests are failing all over the place, test your assumptions. Hopefully there’ll be one or two failing tests there that point you to a solution to your problem. If there aren’t, then at least you know what’s not causing the problem. And, when you do find the underlying problem, you can add the new assumption to your tests for later.

I’ve just been working on Typo and found (rather usefully as it happens) that, if you add counter caching to a model, the model that holds the cache field will call all its save/update hooks whenever the cache field is updated.

Which is a little odd; it could be argued that simply adding what should be an ‘invisible’ cache field to a model shouldn’t go changing its behaviour in this way. So, I’ve created an assumptions_test.rb file and written the behaviour up as a test. Now, if David Heinemeier Hansson decides that this is undesirable behaviour and changes it, we’ll be able to see what’s going on.

The idea (as is so often the case) comes from Kent Beck. In this case, from Test Driven Development. One more book by Beck that deserves to be on every programmer’s bookshelf.

Another Two Cultures

Posted by Piers Cawley Fri, 02 Sep 2005 21:47:00 GMT

So, I’m temping now, just another admin worker bee for the council. I can’t say that I’ve found my vocation, but it’s certainly an eye opener.

All my adult life, I’ve seen a computer as an amazingly flexible servant. If it doesn’t yet do what I need then it’s possible to program it so that it does. That’s what computers are for after all.

This seems to be rather a long way from the experience of the people I’m working with. For them the relationship is inverted. The servant becomes the master and they have to conform to its way of doing things. Flexibility disappears.

On my first day I spent some time keying in data from feedback forms into a badly designed Access database. I was walked through the process which involved inputting data into the table view. This isn’t necessarily a bad way of doing things, but some columns were supposed to be set to one of five satisfaction levels, and those levels weren’t simply numbers, they were text: “Excellent”, “Good”, “Satisfactory”, “Poor” and “Don’t Know/Not Applicable”. Not fun to type in repeatedly.

So I spent 10 minutes setting up a form complete with combo boxes and other appropriate devices to ensure that the data entered was valid, with the added bonus that data entry through the form was way faster. I estimate that it would have taken me at least half an hour to input the data through the table view, and I wouldn’t have a great deal of confidence about its validity. With the form, I had the data input within 10 minutes of finishing the form. Bear in mind that this is the first time I’ve ever used Access; it just seemed obvious that anything that called itself an end user database would be able to do what I needed.

Before I started the job there were already 200 entries, all apparently input by hand. Nobody had taken the apparently simple step of adding a form to make life easier. (Someone had, but it was a terrible form with an insane tabbing order, and nobody seemed to know about it).

It’s terribly easy for programmers to dismiss non-programmers as stupid, but they’re really not. There’s a schism between users and programmers that’s as fundamental as the divide between C.P. Snow’s Two Cultures

I’ve written, indirectly, about this before, but this is the first time I’ve seen the difference so plainly. Mainstream software like Microsoft Office becomes more and more programmable with every iteration and those features hardly ever get used by end users. And end users are the people who really could benefit from this stuff. They’re the people who know what they need the software to do. The divide tends to mean that programmers implement what’s easy for them rather than what’s Right. So users, unfamiliar with the power of programmability, end up feeling that a bad ‘solution’ has been foisted on them.

Picking another example, there’s a bookings system here. It’s terrible. Things that should easy to do in software end up being done by hand—one obvious example is when you use a canned query to find all of a client’s bookings, the list that gets returned isn’t in date order. If you book a room to someone the system doesn’t check that the room’s available, you have to check by hand first (but that’s a pain, because, as before, the list of bookings for a room aren’t in date order)... By any measure, the software these people are working with is terrible. It’s not as if it’d be hard to fix, simply tweaking a couple of queries would make things noticeably better.

As far as I can tell, the people who use this system never met any of the people who wrote the code. Or maybe they never had a chance to play with what’s possible, so they don’t know that software doesn’t have to be this bad.

The Usual Sermon

As those of you who’ve been reading this blog for a while can probably guess, this is the bit where I point out that Agile methodologies win big in this situation. Development that gets a rough model into the hands of the users and then debugs its way to full functionality through a dialogue between users and developers will end up with a more habitable product.

The real power of the conversational approach is the conversation itself. If I can get immediate clarification from the user; if my development practice means that I can say “I think I’ve got an idea that’ll make this easy for you, give me half and hour and have a demo for you”; if I can then deliver running code that shows what I mean, then that can only be a win.

It might take a little more time (the Agile people will tell you it’s actually faster because you don’t waste time on unnecessary code and endless meetings and requirements gathering—I tend to believe them) but I’m prepared to bet that the resulting code will be a great deal more robust and useful. Not just that, but the users will have learned an important lesson about the flexibility of code, which just has to be a good thing. Even if users never learn to program themselves, the knowledge of exactly how flexible these tools are is empowering all by itself.

I’m not sure I’d go so far as to recommend that every programmer out there goes and spends some time working in an office doing the daily admin grind, but if you do find yourself in that position, keep your eyes, ears and mind open. There’s a great deal of good stuff to learn—who knows, you might just come up with the next great product.

The Quality Without A Name 1

Posted by Piers Cawley Tue, 29 Jul 2003 11:06:00 GMT

The Quality Without A Name is a phrase coined by Christopher Alexander in The Timeless Way of Building to describe the feeling of satisfaction and contentment engendered by good building. He later went on to call it ‘life’, but a friend of mine described it as ‘The Tao of Building’, which seems rather appropriate too. The Timeless Way of Building is a fantastic, if somewhat overwritten book, introducing Alexander’s themes and ideas about how modern architects and builders can recapture the qualities inherent in great (usually old) buildings.

Alexander later went on to crystallize his ideas about how to lay out cities, towns, neighbourhoods, houses, rooms, windows, etc in his massively influential book, A Pattern Language, in which Alexander and his co-authors attempted to set down a ‘language’ that would enable anyone to design and build somewhere that possessed the Quality Without a Name for themselves. Sadly, as they admit later, they failed in this attempt; efforts to use this pattern language by laymen resulted in interesting, but flawed buildings. Despite the failure (in Alexander’s terms) it’s a great book; the prose can be a little annoying at times, but the analysis is deep, and mind-changing. Here’s an extract from one of the patterns:

208. Gradual Stiffening

The Fundamental philosophy behind the use of pattern languages in buildings is that buildings should be uniquely adapted to individual needs and sites; and that the plans of buildings should be rather loose and fluid, in order to accommodate these subtleties.

[An essay describing the problem more fully, and the reasoning behind the solution presented]

Therefore:

Recognize that you are not assembling a building from components like an erector set, but that you are instead weaving a structure which starts out globally complete, but flimsy; then gradually making it stiffer buit still rather flimsy; and only finally making it completely stiff and strong. We believe that in our own time, the most natural version of this process is to put up a shell of sheet materials, and then to make it fully strong by filling it with compressive fill.

Look, Agile Building!

Alexander and his co-writers have found a remarkably powerful way of managing complexity by isolating parts of the process of building in individual patterns, but neatly tying them into the greater whole by their use of introductory and closing paragraphs to explain the context in which a pattern is used. When I read it, I find I’m constantly flipping back and forth to look at these contextual patterns that support (or use) the pattern that I’m concentrating on. The book itself has the Quality Without a Name.

It was only after I’d read The Timeless Way and A Pattern Language that I came across the idea of Design Patterns in programming (In fact, I was working as a contractor and had a copy of The Timeless Way on my desk when a coworker spotted it and made a remark along the lines of “Ah, going back to the source eh?”, which he then had to explain as I didn’t know what he was talking about.) when a friend lent me the Gang of Four’s Design Patterns.

I don’t really like Design Patterns. Too many of the patterns seem to be concerned with working around problems with the static nature of C++ and Java—not exactly useful if you’re used to a more dynamic OO language. Another, deeper failing, is the disjointed nature of the patterns presented; there’s no attempt to tie the patterns together in a coherent language and the whole thing feels like a mishmash of ideas waiting to be turned into a finished book.

There is one software patterns book I’ve read that gets it though, that has The Quality Without A Name in the same way that A Pattern Language does. That book is Smalltalk Best Practice Patterns by Kent Beck. If you don’t know Smalltalk, don’t be put off by that title; a very sizable fraction of the book can be applied directly to any suitably dynamic OO language (Perl, Python, Perl 6, Javascript…) and the syntax of Smalltalk is virtually nonexistent and easy enough to pick up.

The book works well because Beck, quite deliberately, limits its scope to the tactics of coding. Instead of going for the big things, we’re dealing with the nuts and bolts: how to choose good names, how to write methods in ways that encourage reuse and flexibility, how to keep things loosely coupled. Beck explains this stuff with concrete examples and simple rules, that work phenomenally well together. It’s hard to put my finger on why it works so well, but my gut feeling is that it’s because Beck has not forgotten the importance of context.

Very few of the patterns are strictly standalone, they refer to each other up and down the ‘levels’ of the various patterns and the individual patterns are small enough, and well enough supported by the other patterns in the language that they remain tightly focussed on the issue they address.

Smalltalk Best Practice Patterns is a complete pattern language, something that I’ve not seen achieved in any other software patterns book (though Martin Fowler’s Refactoring: Improving the Design of Existing Code gets pretty close.) It’s easy to read; full of practical wisdom from someone who knows their stuff and can explain it well.

I recommend this book wholeheartedly to anyone who wants to become a better programmer, and especially to anyone who does object oriented programming in a dynamic language of any kind. If you find me in a bar amongst programmers, and we’re talking about how to get better at our craft, then I’ll almost certainly be banging on about how good this book is.

I believe the Java types are fans too, but if I were a java programmer then I’d find the kind of flexibility inherent in Smalltalk as expressed in this book would just make me want to abandon Java in favour of something more expressive.



Just A Summary