In my previous post I introduced a few lean concepts and set out to tell a tale how those concepts can be applied to the day to day task of cutting code... I picked 3 areas, reducing waste, removing artificial dependencies and building quality into the process.
Let’s start with waste. Waste in the software process has many disguises... In lean manufacturing a large stock inventory is waste. Tom and Mary highlighted that unused features are essentially an inventory; an unused feature is a waste. Another, and probably a much more obvious waste to non-lean thinkers is a bug. Think about this, bugs in unused features are utter waste!
What are unused features though? The clear unused feature to a user is a screen they never use. But to a developer, it’s over engineered code, generic frameworks that have a single application, developing something that already exists (the not made here syndrome)... Agile methods work hard to reduce the statistics of unused features by not having big up front specs, by constant demonstration of software and by re-prioritisation of work backlogs. But developers must also work hard not to create code waste. YAGNI – you aren’t going to need it. It’s a simple statistic, the more code the more bugs. No code, no bugs. We can’t yet write no code to implement solutions (unless you’re a SharePoint guru :) ) so we must aim to write as little as possible. I said before I wouldn’t focus on process, but it is absolutely crucial that you develop the least amount of features for a system that will leave your customer delighted. With that digression out of the way I’ll assume you’re now working on a feature that will be used 90% of the time – how do you make sure you don’t introduce waste in code?
Well here’s a paradox – the answer is to write more code, specifically – write test code. Why isn’t test code waste, the user doesn’t use it the business doesn’t get value from it – its waste? That argument is valid sometimes, sometimes there just isn’t time, sometimes you literally do have a day or two to get something out the door, then test code would be waste. One thing to remember in everything you do is that being pragmatic is the most important thing... The pragmatic guy needing to meet a new regulatory requirement (ignored by the business for months) will get something out the door. The same pragmatic guy also will write tests, he’ll make sure when he’s not commercially constrained, he builds time into his project to build tests.
I can remember having a discussion once with a finance director about project timescales, and being open and honest with him I explained the need to do certain things. He doesn’t care about the software development process or the tasks I have to do to give him software that’s going to make him hundreds of thousands of pounds a month. All he cares about is the fact that if he had it now, he’d be making that money and every day he doesn’t have it he’s losing that money. But, he also understood that me not doing a job properly could result in his call centre not being able to operate and not making any money – so reluctantly, he let me do it properly (pragmatically) (he still squeezed me, but we dropped features not quality).
I think it’s clear enough that if you write tests it will take longer to deliver the solution (there’s simply more to do). In fact, Microsoft have done some empirical research and found it does take longer (have a read here http://research.microsoft.com/en-us/news/features/nagappan-100609.aspx). But they also found that teams using TDD (Test Driven Development) had a lot fewer live defects. TDD measurably increased in process quality. Again, there are two sides to the argument – if a commercial pressure dictates that you simply must get something done you may be willing to have a few live defects (I’ll talk more about quality in a later post...).
A commonly used approach with TDD is “red green refactor”. Write a test, run it; it will fail (red). Make the test pass (green). Then refactor. The idea behind it is you write the least amount of code possible to get the test passing, thus ingrained into the approach is the concept of writing less code.
The refactor step is crucial. Without it, you would repeat yourself... Repeating yourself results in more code (thus more bugs). So, refactoring is also a critical part in writing less code. The key idea with the refactor approach is that you only introduce something when you know you need it. You don’t start off from a point thinking you’re going to need it and write more code than you actually need. The likelihood is you won’t need it, so it’s waste.
TDD should also mean you write fewer tests too. Bashing out a load of code (with loads of things you’ve added in that you don’t need) means that when you retrospectively add tests you need to test more stuff, thus write more tests.
TDD also meets another core lean principle; defer the decision about something until have the information. You only write production code when you know you need it; you only refactor code to use a design pattern when you know you need it... You don’t start off thinking you need it, you wait until you know...
Another aspect of writing less code is using more code that has already been written and tested. The downside of using solutions that already exist is that they will probably do 80% of what you need and have features which you only use 10% of. Now, this is a problem if you have to pay for the software – sinking a lot of money into a something you only use 10% of is wasteful. If that 10% is very hard to do yourself then you’ll probably still spend the money (the best example of this is a database, pretty much all projects need a database, you’d never write your own but you probably only use a small proportion of its features from one project to another...). This is what’s great about Open Source Software (OSS). It’s free. So, there is no money spent thus no incurred waste. There may still be code in that OOS solution that you don’t use, but you didn’t write it, hopefully someone else is using it, so it’s not waste. If you need something, you can contribute to the OSS project and add it in. Or if it’s very specific, you can extend it yourself. Extending existing solutions is also possible with existing paid for solutions, as long as those solutions are extensible. Extending something is again less code from building it all from scratch. Picking extensible components to build a solution on top of is a great way to reduce the amount of code you have to write and test.
I’ve focused on tests teasing out production code, I’ve not touched on the impact tests have on quality – for that, read the last post in this series...