james mckay dot net

because there are few things that are less logical than business logic

April 2009

29
Apr

XsltArgumentList violates the Single Responsibility Principle

Can somebody please enlighten me as to why XsltMessageEncountered and AddExtensionObject are members of System.Xml.Xsl.XsltArgumentList?

It seems like a violation of the Single Responsibility Principle to me — neither of them are anything to do with the list of arguments that you pass into your transform. It would make more sense if they were members of XslCompiledTransform instead.

27
Apr

Using jQuery? Check out jQuery UI

I’ve been a fan of jQuery for quite some time now, but for various reasons I’d never got round to investigating jQuery UI until earlier this week, when I had my attention drawn to it when I was asked why I hadn’t used it in a project that I’ve been working on. So this weekend, seeing as I needed a date picker and a tab control for another project, I decided to download it and have a tinker.

It’s a whole bunch of UI widgets and interactive features that sit on top of jQuery, in much the same way as Scriptaculous sits on top of Prototype, and I’m pretty impressed with it. It’s every bit as easy to use as jQuery itself, and it follows the same philosophy — for example, you can add a date picker to as many textboxes as you like with a single line of code:

$('.datepicker').datepicker();

There are other widgets in addition — an accordion, an in-page dialog box (which seems to be a possible alternative to Cody Lindley’s Thickbox), a progress bar, and a slider. Interactions include drag and drop, resizing, fancy selecting, and drag and drop sorting, and there is a whole bunch of interesting effects and transitions on top of that. There are also seventeen different visual themes to choose from, or alternatively, you can design your own either manually or using a handy web-based theme roller application.

There’s quite a lot of code to it — a full installation with one of the seventeen themes on offer will add 300K to your page download, so it’s probably not ideal for pages on your site that get a lot of traffic from different visitors. But you can reduce the size of the files to only include what you need in a custom generated download. If you are already using jQuery and are looking for a date picker, or a tab control, or any of the other widgets and effects that it has to offer, it’s well worth checking out.

20
Apr

Some thoughts on the role of open source experience in recruitment

Jeff Atwood wrote an interesting post the other day where he asked the question, Is Open Source Experience Overrated? He quoted an anonymous developer who had lamented not being able to find a job despite being the architect of a couple of open source projects:

One company seemed impressed with my enthusiasm for the job but it was part of their policy to provide coding tests. This seemed perfectly reasonable and I did it by using the first solution I thought about. When I got to the phone interview, the guy spent about five minutes telling me how inefficient my coding solution was and that they were not very impressed. Then I asked whether he had looked at the open source projects I mentioned. He said no – but it seems his impression was already set based on my performance in the coding test. The coding test did not indicate what criteria they were using for evaluation but my solution seemed to kill the interview.

I must confess that I was a little bit incredulous when I read this. It seems the correspondent was expecting the recruiter to consider his open source contributions as a substitute for his poor performance in the coding test — and it would be an irresponsible recruiter who did that.

The problem with open source contributions is that they don’t necessarily tell a recruiter what they need to know about you. They indicate passion and enthusiasm for programming, which is a plus, but they don’t necessarily indicate competence — and passion is no substitute for competence. In fact, some open source projects, such as this example cited by Ayende the other week, are very badly written and do not reflect well on the developer. And in the recruitment process, it’s competence that a responsible recruiter will be looking for first and foremost. That’s why it’s so important to have a coding test. The team needs to have a certain baseline standard, and that standard needs to be treated as a “must have” — failing the technical test should be an automatic “no hire,” regardless of passion or experience. Yes, they should take a look at your open source contributions, but they only really become relevant in the later stages of the recruitment process, once they have carried out the technical screening and are getting into the final round of interviews.

Here are some examples of things that a recruiter may want to know about your abilities that he or she is unlikely to find in a typical open source project:

  • How quickly you can write code
  • How quickly you can troubleshoot code
  • How quickly you can learn new technologies
  • The extent of your understanding of the company’s core technologies (how much you have committed to memory, and how much you need to refer to the documentation)
  • How well you can understand and implement customer requirements
  • How clean you can keep your code when working to tight deadlines
  • Whether you can grok recursion
  • Whether you understand Big O Notation and its implications for performance
  • How well you can integrate with the rest of the team

Different companies also have different attitudes towards open source. The ones that are most likely to be interested will advertise job openings in the open source community itself — they reason that that way they have a generally richer pool of talent to draw on than the hordes of unqualified and mediocre people that you get in places like monster.com and recruitment agencies. Larger organisations, on the other hand, are only likely to take notice if your contributions are to a project that they’re actually using, such as NHibernate or Tomcat, and some companies actually have a prejudice against it, so it pays to do some research and bear in mind that YMMV.

One other thing. If you want to pitch your open source contributions to your prospective employer, you need to make sure that your code is the best quality that you can give it. You might find that they take it into account in ways that you hadn’t expected, and if you’re doing stupid things such as silently swallowing exceptions, or writing thousand-line, hundred-parameter, multi-responsibility, copy-and-paste methods, or giving them names like DoIt(), or if your code formatting is sloppy and difficult to follow with inconsistent indentation, it may work to your disadvantage if they ask a technical reviewer to look at it. Open source coding isn’t like coding for work or profit: you have no deadlines, so you can afford to give it a lot more tender loving care.

14
Apr

Beware of second hand contracts

There is a corollary to the concept of technical bankruptcy that I wrote about last week. When you take over a project that was originally built by another company, there will obviously be the inevitable ramp-up time on top of that, as your developers get to grips with the system, but on top of that, you are taking on that project’s technical debt.

We learned this the hard way with one of the worst projects I ever worked on. The client needed a new front end to their website in a timescale of only six weeks, and the sales guys said that of course we could do it, as non-technical sales guys generally do. However, only when they had signed on the dotted line did we get to look at the code.

The levels of technical debt were horrendous. The system, which had little or no coherent documentation, consisted of dozens of classic ASP files of extremely ugly copy-and-paste code, two thousand line stored procedures with up to eighty parameters each, and I’m sure that some of the identifier names were in Klingon. Five months of late nights, much stress and one ruined Christmas later, we eventually delivered something that I considered approximately halfway between “me-ware” and “pre-alpha” in quality, then spent the next two months frantically fixing bugs in the system.

There is a cautionary tale here. When you are taking over a system that was developed by another company, there is absolutely no way that you can give any estimates whatsoever until you have looked at the code base. A five-stage booking form may not sound like a big deal, but when you have to plug it into convoluted and undocumented spaghetti code that borders on the incomprehensible, all bets are off. In this case, the business logic was all in the two thousand line stored procedures, which were designed entirely with the workflow of the old site in mind, and the workflow of the new site was substantially different. On top of that, the client also wanted web services integration, so we had to build a fairly complex abstraction layer on top of it.

In any case, you should certainly ask why the previous company isn’t supporting it any more. It may be that the technical debt grew to levels that they can no longer handle, and that is why they are fobbing it off onto you.

06
Apr

When technical debt becomes technical bankruptcy

When clients and managers insist on a quick and dirty fix, they usually think that this means we only implement the “must-have” functionality, and leave aside the “nice-to-have” and even some of the “should-have” stuff. Okay, so we might need to reboot the server once a month or so, or we might need to go directly into the database using SQL Server Management Studio whenever prices change, but we can live with that, they think.

However, there is an unseen and potentially much more damaging effect of the quick and dirty fix, that developers, managers and clients all need to be aware of: technical debt.

Martin Fowler explains it like this:

You have a piece of functionality that you need to add to your system. You see two ways to do it, one is quick to do but is messy – you are sure that it will make further changes harder in the future.The other results in a cleaner design, but will take longer to put in place.

Technical Debt is a wonderful metaphor developed by Ward Cunningham to help us think about this problem. In this metaphor, doing things the quick and dirty way sets us up with a technical debt, which is similar to a financial debt. Like a financial debt, the technical debt incurs interest payments, which come in the form of the extra effort that we have to do in future development because of the quick and dirty design choice. We can choose to continue paying the interest, or we can pay down the principal by refactoring the quick and dirty design into the better design. Although it costs to pay down the principal, we gain by reduced interest payments in the future.

Now there are times when technical debt is an appropriate strategic decision. Often, you need to get to market quickly with your website in order to obtain a competitive advantage. Sometimes, there are hard deadlines to meet. However, just as with financial debt, you need to be aware that you are taking on a certain amount of technical debt, because it will need to be repaid sooner or later.

Consequently, when you make the strategic decision to accrue some technical debt, you should always allow for some time to repay it at regular intervals — refactoring, adding more unit tests, documenting the system, and maybe even rewriting some components from scratch a second time if they are particularly messy. If you don’t, and the situation is allowed to get out of hand, you can end up with technical bankruptcy.

Technical Bankruptcy is the point at which levels of technical debt become so overbearing that the project is effectively doomed. This is due to two serious and crippling effects of technical debt:

1. Making changes becomes much harder.

One of the quickest ways to build up technical debt is to copy and paste large sections of your code. Programming purists rightly regard copy and paste as evil — it violates the “once and only once” rule and makes it much harder to make changes later on. However, it can add extra functionality into your program much more quickly than doing things the “correct” way. Many of the other programming anti-patterns, such as magic numbers, meaningless method names such as “do_it”, and so on, fall into the same category — shortcuts which involve a trade-off between getting things done now and getting things done in the future.

However, these are the less complex cases. More serious are the higher-level shortcuts: poorly designed database schemas, tight coupling between the tiers of the application, a lack of preliminary analysis and design, and so on. Nevertheless, whatever the cause, the result is that by asking for quick and dirty hacks today, you are potentially blocking yourself off from asking for quick and dirty hacks tomorrow.

2. Finding developers to work on the project becomes much harder.

Make no mistake about it: working on a project that has an excessive amount of technical debt is a depressing, discouraging, and disheartening experience. It can mean going for days or even weeks on end banging on the keyboard with little to show for it and getting shouted at by your boss for not delivering on time. It saps morale and by extension productivity, and this can spill over onto other projects and pull the rest of the team down. And what do developers do in that kind of situation? If they’re any good, they go and find somewhere else to work.

This compounds the problem even more. When a developer leaves, you have to recruit someone else to fill their place. This means placing an ad wherever you normally place ads, spending time filtering CVs, conducting phone screens, technical tests (you do give potential hires a technical test of some nature, don’t you?) and interviews, and then once you find a suitable candidate, there is the ramp-up time where they are actually getting to grips with the system — and no prizes for guessing what technical debt does to the length of this ramp-up time.

Although we are in the throes of a recession, there is still a massive shortage of good developers. It’s amazing just how many working programmers there are out there who can’t even handle the most basic challenges such as the FizzBuzz problem, and who get by merely by copying and pasting SQL injection vulnerabilities from ten year old PHP tutorials, or by pestering their more talented and knowledgeable colleagues for help at every step of the way and proving to be a net drain on the company’s resources. These are the kind of developers who have no concept of technical debt in the first place, and will just make things worse faster.

I would say that when you start to find it difficult to get good developers to work on a project for any length of time, it is a sign that your project is in serious trouble.

Is a total rewrite the answer?

Managers are invariably suspicious whenever a developer recommends a complete rewrite. Joel Spolsky wrote an article a while ago asserting that complete rewrites are a bad idea, and every time I say that X needs to be rewritten, this article is quoted back to me as a stock excuse for declining my suggestion.

Now the managers have a point here. A total rewrite from the ground up is the nuclear option: you run the risk of throwing away a whole lot of undocumented business rules, corner cases and bug fixes, and a complete redesign of the administrative interface means staff re-training and a deluge of support calls. Besides, developers can be a bit trigger-happy when calling for a total rewrite. We tend to be a pretty opinionated bunch, and very often we will call Someone Else’s Code complete garbage simply because we don’t understand it properly. But given a bit of time, most developers will manage to settle down into a new code base and will be able to start improving it and cleaning it up by a process of small, incremental refactorings as they go along.

Nevertheless, once you reach the point of technical bankruptcy (where technical debt becomes so overwhelming that the project is effectively doomed), a total rewrite might save the day, and maybe even provide some added value by clearing out certain business rules and systems that were put in place only as workarounds for bad design decisions in the first place. However, it would take a brilliant and determined developer, probably working on it as a skunk works project, to pull it off. Best to avoid getting into the situation in the first place, by paying down your technical debt sooner rather than later, and only hiring developers who know what they are doing to work on the project.

02
Apr

Continuous Deployment: radical idea or April fool?

No doubt many of my readers will be aware of the concept of Continuous Integration. It takes daily builds one step further by building your project every time you check in some code, running all the unit tests, creating your packages, and generating some reports. It means that if you break the build, you get fairly quick feedback on the fact. Continuous Deployment takes this even further still, by automatically deploying every successful build to your live production environment.

Now perhaps it’s just coincidence, but I first came across the concept of Continuous Deployment yesterday morning when I saw this headline from Simon Willison pop up in Google Reader — on April Fool’s Day of all days. However, clicking through to the article he linked to led me to a couple of blog entries written back in February, and a Google blog search turned up several dated hits indicating that this isn’t a joke concept that was churned out just for the day, like the old classic about Swiss spaghetti harvesters. Believe it or not, apparently some people are actually running automated deployments to their live production environment of every last check-in.

But is it a good idea?

Well let’s just say it has that kind of radical, crazy startup feel to it. It’s the kind of thing that you do to prove to lesser developers that you’re in a completely different league to the rest of us, and then everybody else tries to copy you and falls flat on their face because it doesn’t work in their situation, or they’ve completely misunderstood you, or they haven’t done it properly in the first place. Either that or else as link bait — a bit like Joel writing his own compiler, or Paul using Lisp for everything.

I guess you could get it to work, if you have the right kind of team, the right kind of processes and the right kind of people working on it. But in effect, you are doing away with your QA and change control processes altogether, and relying entirely on your unit tests as a substitute. I don’t think much of this idea at all myself. Unit tests have their limitations: they can only ever cover a tiny fraction of the possible use cases for your code; making a change to one part of your system often introduces a bug in another part of the system that your unit tests hadn’t foreseen; there are things that it is very difficult to test properly through unit tests, such as user interfaces or external services; and your unit tests themselves may have bugs and be testing the wrong thing anyway. You just have to have them backed up by some manual ad-hoc testing to find more possible ways that issues could crop up.

You could of course — and indeed probably should — deploy continuously to a SAT or UAT environment: that way, your internal testers can evaluate changes fairly quickly and you can adopt a truly agile approach. However, deploying continuously to your live production environment sounds pretty reckless to me. I’m still tempted to call April Fool on this one.