torsdag den 16. juli 2009

Inspirational reading material

I've been reading a lot of books during the last few years ... it feels like I've stumpled upon a huge pile of books, that all seem really important for me to read. Every time I finish a book, the backlog of books in front of me has grown with 3-5 books, that I simply must read. Articles as well are piling up, and it sometimes strikes me, that maybe I am not going to catch up - maybe I am going to have to filter some of the books or articles away ... sigh ...

Anyway, I find all kinds of litterature a great source of inspiration, and therefore I spend a lot of time reading. Surprisingly (to me at least) most of the books I've read recently have turned out to be really great books. Books that made me think a lot about how I work and write software, books that have actually changed my ways of doing these things. When I experience these books having such an effect on me, it is hard for me to resist the temptation to share the knowledge I've attained.

So have made two lists for You to have a look at:

Currently I am reading Andy Hunts book Pragmatic Thinking and Learning, a very interesting book about how our minds work, how to improve our brainfunction, and how to attain higher levels of expertice. I hope to finish reading it in about a week, and then I'll post a more thorough review of it here.

torsdag den 9. juli 2009

How much time do we have?

To night I saw a movie called School Of Life, featuring Ryan Reynolds as an off-the-charts charismatic school teacher. The movie was "above average", but the thing that stuck with me afterwards was this motto Ryan had in the movie. He asked his pupils rhetorically: "How much time do we have?", and he answered the question: "Not a lot!" His point was, that with only a limited time in this life, you better really make every moment count.

Now how does this relate to software development?

Well, my thoughts were along the lines of: Take pride in your work, and make sure you produce high quality software every day.

While this makes sense, I suddenly realized that this motto can be seen as a recommendation of agile development: With only a limited time before the deadline of the project, make sure you spend you time working on the most important things at all times.

This is part of the definition of most agile methodologies, and in my humble opinion, the most significant one. The fact that the customer knows, that we as developers always focus on the customer's top priority tasks, is what it's all about!
That is how we get the customer to buy into the agile way of running projects.
That is how we make sure, that the customer ends up with a system, that works the way the customer wants, and that the end users will enjoy using.
That is how we as vendors will gain customer satisfaction, repeat business and success in the market.

So if you are using a non-agile methodology, I'd say it's about time to begin looking into topics like agile, Scrum, TDD / BDD, etc.

We don't have much time, so we better make it count!

mandag den 29. juni 2009

Working Effectively with Legacy Code - part 2

One of the biggest challenges, when it comes to adding tests to legacy code systems, is dependencies between different parts of the system. Dependencies comes in lots of different flavours, some of which are: Constructor parameters that must be supplied, properties that must be set, globals being referenced from anywhere, external libraries being used, framework APIs being used, databases, and also all kinds of physical devices like discs, printers, etc.

The problem with dependencies are, that if you want to test a class in a way, that isolates that class from anything else, so you can easily detect changes in functionality, the dependencies must be taken out of the picture. If not, a potential failure could be caused not only by the code we touched, but also by anything that code depends upon. You need to be able to construct an object of the class under test in an way, where you are able to control the object's environment completely.

So how do you remove dependencies? Well, it depends ... (pun fully intended)

In the book "Working Effectively with Legacy Code", Michael Feathers includes a wealth of techniques for breaking dependencies - in fact, about the last third of the book is dedicated to this very topic. And the really great thing is, not only does he teach us a lot of techniques, he also attempts to bestowe within us, the wisdom to choose the optimal technique for any specific type of problem and dependency. Let me just give a very few highlights about constructor parameter dependencies here:
  • If you control the source code for the parameter classes, you should be able to inherit those classes to make fakes, and just use those during tests.
  • If you don't control the source code, you could create a new class, that wraps the parameter object (a proxy if you will), refactor the constructor to use this new class instead of the parameter class, and have it behave differently during test than when in production.
  • A third technique could be to use mocking to abstract away the dependencies.
A few highlights about references to globals too:
  • You could wrap your globals in a static class, that exposes those through static properties, and making the properties behave differently during test than when in production.
  • You could try to remove the global all together by injecting the value as a constructor parameter or as a property.

These techniques and many more are explained in the book in crystal clear details, and with example code to match. As I read through the book, I can't help but thinking, that I should have read this book back in 2005, when it was published, because it would have saved me so much pain and anguish by now ... well, in this case, the phrase "better late than never" is very appropriate: These techniques will continue to be valuable for a long time. So no excuses left - Read the book!

søndag den 21. juni 2009

Working Effectively with Legacy Code (WELC)

Well, two weeks went by pretty fast, and I haven't had very much time to myself, so I have still not finished my new Bible, WELC ... however, I've been preaching the subject to several colleagues and members of the development community, and I've received lots of positive feedback. This affirms my belief, that this book will change the way I (and hopefully other developers around me too) works with legacy systems.

In this post I'll dive into one of the concrete techniques from the book, so You get an idea of why I'm so excited about the book. The technique I have chosen is from chapter 6 "I Don't Have Much Time and I Have to Change It" from the book, and it is merely meant as a teaser - I want You to read the book for yourselves and form Your own opinions. I will show more methods soon.

The "Wrap Method" technique.

The main problem you face, when having to add new functionality to a legacy system, wether a bug fix or a new feature, is inadvertently introducing new bugs. Since legacy systems does not have (sufficient) tests, changing code is feeling close to Russian Roulette, only with 5 bullets and 1 empty slot in the revolver, and not the other way around.

The Wrap Method technique allows you to add functionality to existing methods without the risk of introducing new bugs. Sounds like magic, right? Well it isn't, it is just a very straightforward application of encapsulation and separation of concerns.

The idea is, that if you can characterize your change as appending new functionality at the beginning or at the end of an existing method, you create a new method containing the new functionality plus a call to the existing method. Then you swap the names of the existing method and the new method. This means, that every call to the original method suddenly hits the new method, which in turn calls the original method before or after executing the new functionality.

Here is an example. The following method is the one you want to add functionality to:

public void MethodA([lots of parameters])
{
// Hundreds or thousands of lines of complex functionality
}

You want to include a call to another method, MethodB, in MethodA. However MethodA is complex enough as it is. So we add another method, NewMethod:

public void NewMethod([same parameters as MethodA])
{
MethodB([some parameters]);
MethodA([lots of parameters]);
}

Finally we swap the names of MethodA and NewMethod:

public void NewMethod([lots of parameters])
{
// Hundreds or thousands of lines of complex functionality
}

public void MethodA([same parameters as MethodA])
{
MethodB([some parameters]);
NewMethod([lots of parameters]);
}

This way, all calls to the original MethodA now hits the new MethodA, which includes a call to MethodB, and we have not changed a single line of code inside MethodA. So the only potential bugs introduced is in the call to MethodB - quite a bit easier to debug than debugging MethodA, right?

This technique demonstrates one of Michael Feathers' principles: Don't change code without tests to validate your change.

søndag den 7. juni 2009

My very first blog entry

This is my very first blog entry, and I've been putting it off for way too long.

For the last three years, I've been thinking a lot about the way, we build and maintain software. By "we" I mean both the developers at the company I work for, but also in the software development community as a hole. I've been reading a lot of books, and I've attended quite a few conferences, seminars and lectures on software development, and I have finally reached the point, where I feel I'm ready to begin contributing to the subject myself. This blog (On the way to better software) is my first real attempt to give something back to the community, that has taught me so much over the years.

In this blog entry, I want to share my thoughts on the book, I am currently reading: "Working Effectively with Legacy Code" (WELC) by Michael Feathers (check out the link).

To add a little perspective on why this book caught my attention, I'll tell a little about the job, I've had since November 2004. I work at a consulting company / ISV in Denmark, and lately I've been assigned to a product team building one of our products. 

The product was originally built in PowerBuilder about 7 or 8 years ago, but was converted, line for line, to C# by an outsourcing partner 3 years ago. This means that the application architecture was not improved, and whatever oddities were in the original program, is still present today, only magnified by the brutal translation from PowerBuilder to C#.

I was assigned to this project because productivity on the team is going down, the number of hours per bug fix and per change/expansion is rising, and the morale among the developers is suffering. My task is to help turn this project around.

The first thing I did was to have a few hours of brainstorming with the developers on the team. I wanted them to tell me all the things about this project, that felt like a pain. This included build procedures, architecture issues, bug reporting procedures, change request processes, time tracking and much more. This brainstorming session resulted in a list of almost 30 issues, or impediments, that the developers felt were most painful.

The next step is to assign each issue with a severity level and an estimate. I want to indicate which issues are the most harmful ones. The estimates will be qualified guesses made be myself and a few of the most experienced developers on the developement team, and they will indicate which issues will be the quickest to fix. These two numbers together will (hopefully) indentify the "quick wins", which will be started up first.

To get back to WELC, I began reading the book a week ago, and immediately I sensed, that this book will change the way I think about legacy code, and how to handle legacy code. 

First of all, the author defines legacy code as code without tests. Think about this for a minute: You can be writing the cleanest code, using all the best practices of software architecture and of your current development platform. But if you're not writing the tests to verify and document your code, your code becomes legacy code immediately! This means that the next developer looking at your code, will have no way of knowing what your code is supposed to do, other than external documentation of course. The effect is, the next developer will never know if the code is behaving correct or not! This is of course very, very bad!

So we should all be doing TDD, or at least be disciplined enough to write the tests for our code, before we release it to the public.

The focus of WELC however, is not TDD or the likes, but more generally how to improve code quality, bug fix hours, change request hours and morale on legacy code projects. And the key is to add tests. Not tests to cover every line of legacy code, but enough tests to cover the code changes we want to make. In order to do this, code dependencies must be broken, some code will have to be refactored, and all new code must be covered by tests. WELC lists lots and lots of techniques to do this, and the author takes you through very clear examples on how to employ these techniques.

I have not finished reading WELC yet, and I can guarantee, that this will not be the last time I read it. This book will not only help you save sinking projects, but it will make you think about, how you architect your software on "greenfield" projects in the future. This is indeed a very valuable book, and you should read it today rather than tomorrow.

Mikkel Toudal Kristiansen
On the way to better software ...