Friday, December 31, 2010

Last post for the year, I promise

Listened to a great interview with Alistair Cockburn last night. I love his 'Agile Software Development' book, and this interview was an inspirational reminder of his approach to agile, and the deep reasoning behind the fabulous agile manifesto.

Give it a listen (tell, don't ask)

Writing Legacy Code

The stuff I'm currently working on was written in a week as an experiment in productivity... it ended up with over 300 bugs, though probably only 200 were in the code itself.

One week of coding, six months ago, who'd have thought that something that 'fresh' could be considered legacy - but it has certainly left a legacy behind.

My last posting at my last job had me writing legacy code. I was stuck in a code base that felt legacy and required legacy hacks to get it to do what you wanted. I should have thrown my toys out of the pram, but didn't have the kahunas. That code was 3 months old when I started hacking on it.

It seems that age doesn't have much to do with the definition of 'legacy code'. If this is the case, what is a good definition of legacy code...

Code without tests

Simplez, yes? If your code has no tests:
  • You don't know what it should do
  • You can't trust it does what it should do
  • It's probably highly coupled
  • etc, etc

This means that if you are writing against a codebase that has no tests, you are writing against a legacy codebase. If you are writing code and not writing tests, you are writing legacy code.

(Just for the record, your tests should be automated, and they should be at least unit tests. If you are doing otherwise, you are wasting a lot of time sitting there manually testing every codepath in your codebase)

Logging Token Pattern

Ok, Ok, so this is speculative as I haven't tried it yet, but hear me out.

On my last assignment with ThoughtWorks I was working with my good friend Simon Brunning. We were doing some file processing stuff that was apt to fail, if not on a complete file basis, then at least on a line by line basis.

We wanted to know what went right and what went wrong. Originally the code passed around a bunch of lists that would contain working things and failing things and exceptions (yes, the actual object) and so on.

Brunning created a customised object that tracked the progress of the file processing. It printed nice results when it finished, outlining what happened at what stage. It made the code much nicer, and the reporting much nicer.

For some reason, at the same time, I was thinking about the over abundance of log messages in your typical log, and how useless they are to the poor old Ops staff.

These two concepts gelled. Why not log the bejesus out of your process, but only print things to the log if something goes wrong.

An initial cut could be a 'transaction based' logger... 'start' a log stream, and then either 'render' if something goes wrong or 'drop' if it's all ok.

In this way the Ops team get a shite load of logs, but only if something went wrong. Surely a huge improvement? And/But the developer could put in heaps more info than they might otherwise.

The next level would be to create these custom objects that know how to talk about what they were doing and what went wrong. This would require people to think about stuff, so seems unlikely :)

Both these approaches would have to be thread based (as in: thread local variable), but the second one would have to know what sort of logging/tracking token was being updated within the current Thread. That's not easy, but Felix is up to this kind of thing.

So, given I haven't tried it, what do you think?

How I MVC

So, I'm working in a .Net company that makes applications. Weird. I've only done webapps for the last 10 years or so.

Nice thing about webapps is it forces you to at least consider separating presentation from content, behaviour from interface and so on (often that consideration is ignored and we just write crud, but one is encouraged by the CSS/HTML/Javascript/Webserver separation to at least think about it)

App side of things? No such luck. Everything just goes everywhere.

Now, thing is, I'm working on some projects that started as prototypes, so it is unfair to judge development practices on them (I hope...). They have no tests. They are not written with tests in mind. They have no 'domain model' and very poor separation of concerns.

My company just gave us some 'downtools' time to work on our own stuff, so I did a (prototype) reimplementation of much of the application I've been working on. I did this so I could see how I could write this app with tests, and in turn using the MVC approach that smalltalk encourages.

(I also tried for a tell don't ask approach, and achieved this to a degree, but didn't really push it)

By thinking in MVC terms I end up having to have a 'domain model' - it's the model bit :) This is already a boon as I start separating out the model data and behaviour from the human interface that manipulates it. This means I can use a different (eg testing) interface to manipulate it. Whamo, got some tests. Red Green Refactor Happy

Next comes the view. I hate views. The bit the user clicks on is pants to test, and hence I've always tried to keep this untestable, horrible bit of code as thin as possible. Sure I can have some happy path integration tests, but really, they suck and don't cover nearly the ground a good few unit tests will.

This also separates out the manipulation of GUI elements into one place - and I love separation.

If the view is so thin, what does the UI work? Well, the controller (that's all that's left, right?). So it ends up linking the view and the model, translating between them, maintaining any state associated with the UI (and not the domain) and invoking commands on the domain as needed.

Boy that's a lot. Too much.

So I split the Controller up into the, um, Controller and the ControllerModel (actually I called it ViewModel).

The ControllerModel maintains any state that may be needed for the particular view you are dealing with (eg list of pages in a wizard, internal representations of the GUI elements (and hence translations) etc). This makes it a nice, testable chunk of code, and simplifies the Controller.

The Controller has NO state - it only knows about the things it is linked to (view, model, controllermodel, services). While it makes behavioural decisions, these decisions are based on information drawn from elsewhere.

While still hard to test (lots of mocks/stubs!) you end up just testing that 'when event A is received, object B is called'. The tests themselves end up much better worded - explaining behaviour and interactions explicitly, not having to worry about translations and state.

So how do I MVC? I MVCVM (Model-View-Controller-ViewModel).

(A final note... the controller sits at the centre as a big fat svelte mediator sending commands to all its minions and listening for those minions events. The minions never call/know about the controller)