26.7.09

220 Downloads later…

A while ago I put together a little library that determines internal rate of return for a series of cash flows. This is a problem in the accounting domain and was prompted by the inadequacy of the features in excel. I did not want to haul the whole of excel into the application I was building. I tend to stay clear of Interop if I can help it.

Well the short of it is that the lib averages 1.5 downloads per day. Not much for 15 mins work, but this has led me into thinking that perhaps there is a larger market for reusable math/scientific libraries. How about a DNA sequencing lib?

Now clean it up…

In our attempt to clean up software engineering and make it a more rigorous profession, I assert that testing is one tool that will ensure that the discipline produces consistent results and repeatable quality. Testing should be at the forefront of a developers’ mind, but in most cases it is an after thought. I suppose this is a reflection on the human condition. We are forever optimists hoping that our artefacts will stand the test of time.

Well I don’t live on hope and for me life is a set of precise constructs. Gravity always wins and code breaks. So lets get test-infected.

Writing a good tests assumes:

  • A knowledge of the domain or access to a subject matter expert – can be the product owner
  • An adequate tests framework
  • A testable architecture

As someone once said, “any one can write a programme, it takes a disciplined developer to write code with tests”.

10.7.09

Balancing the risks of tool switching – a heuristic

When/why should a team adopt/change its toolset?

  • If the current toolset is inadequate and results in a loss of productivity
  • If the new toolset is a ground-breaking innovation and not merely a derivation and solves the business problem better than the incumbent
  • If there are compliance/regulatory constraints that mandate the change – for example Sarbannes-Oxley.
  • If the new tools will give you significant competitive advantage in the market place, otherwise the costs of learning/deploying the tools will erode marginal benefits

When should a team not adopt/change its toolset

  • Because it will look good or make the developers appear smarter when included on their CVs – remember the customer has to deal with mess once you have left the site

The day we overloaded the scrum with issues that were not part of the “triumvirate”

The context: A distributed team with very minimal inter-personal contact. Most conversations are by electronic means.

The scrum started out with each engineer being asked the usual trio of questions. The expected responses were given and then a tangential conversation about the best approach to take for a new project took root. Big mistake! Before long we had a virtual bun-fight that risked creating permanent schism within the team.

The lesson to learn from this saga is that face-to-face sessions are best when discussing issues bordering on religion. Once a jihad has taken root within the team then delivery of quality software will be impossible because the team is working against itself.  As a facilitator it is tempting to give additional bandwidth to groaners and the loudest shouters, but this has to be weighed against the greater needs of the team to work as a cohesive unit.

1.7.09

We have survived the death march…what’s next

After the intense and somewhat heroic efforts by the team, a retrospective is definitely apropos. The key lessons learnt are:

  1. Scrum definitely works when used in a chaordic context. What might appear as the ritualized trio of questions, what did you do yesterday, what do you plan to do today, what are the impediments to progress, focuses the development team on what needs to get done.
  2. Working software is the ultimate measure of progress on any software project. If it’s buggy you will have trouble gaining the trust and required acceptance and signoff.
  3. Short feedback loops via daily stakeholder meetings help focus the development team on what needs to get done
  4. Having a developer who also happens to be a subject matter expert will propel the team further.
  5. Don’t change the domain model if it’s not broken. A distinction has to be made between purely technical changes and changing the semantics of the model.
  6. Regression issues will undermine the team and erode user confidence
  7. Make your tech choices before hand and adhere to them
  8. Beware of feature envy - http://c2.com/cgi/wiki/Wiki?FeatureEnvy
  9. Keep the testers close and the customers closer
  10. Retrospective testing of code is much harder than TDD.

11.6.09

A severe case of coders block

With an impossible deadline on my back and a tangle of excel spreadsheets as my spec, I punch the keyboard, but the juice fails to flow in the IDE. The first test says nothing about the problem I am solving. The coffee is insipid; the Ipod sounds like a broken digital record…perhaps the copy and paste coders are on to something…but I let that thought pass. Why bother with reuse if they refuse to use my API. Do I detect NIH?

Making a case for dogmatic Extreme Programming

Refactoring is now a common term in the developer’s vocabulary. However what most developers call refactoring is really hacking. Making a change to the code in the hope that it will work is somewhat analogous to smoking a cigarette whilst filling up your petrol tank. Both will inevitably end in tears. And this is where the dogma kicks in; it is not really refactoring unless you have a safety net of automated tests to verify that the state of the universe has not changed since you  last updated that pesky connection string. A bad test is better than no test at all. I guess that leads on to my next topic…false positives and false negatives. But for now get testing and buy a diesel.

9.6.09

Ok Mr. Customer…your software is late what are you gonna do now?

How do projects get late? Well as Brooks says in the seminal Mythical Man Month, “projects get late one day at a time”. That day the developers spent listening to that lousy presentation or fixing their development environments instead of delivering features, the project was getting late. That day the developers spent time chasing requirements because the product owner could not be bothered, the project was getting late. Kind of reminds me of the boiled frog metaphor.

Scrum and daily releases mitigate this risk, but the can only succeed in an enabling context.

No guts no glory…

Many enterprises pay lip service to agile. They wax lyrical about agility, but the minute one practices the principles that espouse agility, they run for cover in the command and control cave. This cavern contains the usual paraphernalia of document heavy processes, bottled-necked decision throughput and the waterfall methodology. Funny really, but not surprising as some corporate types are quick to latch on to the latest buzzwords without understanding the true essence of the discipline.

As they say…”talk is cheap”. The agile acid test has got to be: ”if it talks like agile;walks like agile and smells like agile then it is agile. A form of agile duck-typing if ever there was such a thing.

23.5.09

The Last Mile

How do you walk your software product through the wilderness of dumb users, dodgy machine builds and missing dependencies?

You want to reduce your support footprint and the dysfunction of dealing with false positives(i.e. it’s your software not my machine syndrome). If you have control of the deployment landscape then a standardised machine build and knowledgeable first line support come in handy. Otherwise online users forums and comprehensive user documentation will help share knowledge of work arounds, gotchas and technical Voodo. The last thing you want is for the development team to be constantly building patches to support all machines under the sun. Doing this robs the team of the precious time required to develop new features and enrich the product’s functionality.

Time and Tide and Software releases…

My team releases software every week regardless of the political landscape or inefficiencies of other departments. Ours is a disciplined and rigorous approach, we aim to be proactive and to keep the momentum forward, never backward. After all this is agile and we embrace the iterative and incremental nature of our game. To the gentlemen from the hydro-methodology this does not make sense. Surely you should only release when the business say so and when the business are ready for your release. If we did that then we would be constrained by the same inefficiencies that plague other teams. And that aint agile. So I suppose time and tide and software releases wait for no man.

2.5.09

Refactoring to a fluent configuration interface

The starting point was a configuration class that had the following definition:
public const decimal AdultFactor = 6;
public const decimal ChildrenFactor = 3;
public const decimal GasKwHMinEstThreshold = 4000;
:
These parameters are always used together in the context of a calculation for gas consumption. The client code uses these config values in the following fashion:

calculatedUsageKw = AdjustUsageForRadiators(calculatedUsageKw, GasConfiguration.AdultFactor,
                                            GasConfiguration.ChildrenFactor,
                                            GasConfiguration.RadiatorFactor,
                                            GasConfiguration.PersonsAtPropertyFactor);
I wanted to give the setting of the gas consumption parameters a fluid feel in the following style
public static IFluentConfiguration Create()
{
var fluentConfig = new GasConfigurationFluent();

fluentConfig.SetAdultFactor(6).SetChildrenFactor(3).
SetGasKwHMinEstThreshold(4000).SetGasPointsMinThreshold(12).
SetGasPointsToKwHConvFactor(400).SetGasWaterHeatingAmount(10).
SetHobGasCooker(4).SetMainRoomFireOnGas(16).
SetPersonsAtPropertyFactor(2).SetRadiatorFactor(5);

return fluentConfig;
}

The client code accessing the fluent configuration interface was refactored to:

private decimal? AdjustUsageForRadiators(decimal? calculatedUsageKw, IFluentConfiguration fluentConfig)

The GasConfigurationFluent has setters that take the folllowing general approach:
public IFluentConfiguration SetAdultFactor(decimal? adultFactor)
{
    AdultFactor = adultFactor;
    return this;
}
And yes my setters have a return value which is in effect the current context i.e. my fluent configuration.After applying this refactoring, a few things became apparent,
1. The method chaining enforces the fact that these parameters exist in the same context and somewhat provides a cohesive view of my configuration interface. The setting of the configuration values is much more concise.
2. The cohesive nature of this configuration hints at the fact that a DSL(Domain Specific Language) could possibly be built around the calculation of gas consumption.

1.5.09

Wide laps

If the benefits of having a wide sturdy lap were ever in question, then look no further. On the left is my company laptop firmly glued to my thigh. The other limb is supporting my XPS M1330; looking on in the background is the Inspiron 1525.