- The Software Development Problem
- The Genius Is in the Simplicity
- Problem Breakdown Exercise
- Exercises to Help You Toward Genius
- Conclusion
The Genius Is in the Simplicity
A genius is a person who can take a complex problem and find a very simple solution that solves it. This solution is usually fairly trivial to implement after you know what it is. Most of us take the easy option, however, and create complex solutions to solve our complex problems. We do this for a number of reasons; the two main ones are as follows:
-
We take on too much at one time.
-
We look at how a similar complex problem has been solved before and try to copy that solution.
Our egos don't help in this matter. We want to show off how smart we are at implementing some complicated solution. We want to justify that we should be paid more and promoted. We don't feel comfortable going to our boss and saying, "That problem was solved in five lines of code, but it took me the whole of the past three days to write those five lines."
Big, Complex Solutions
The trouble with designing these big, complex solutions is that we often then get stuck when trying to actually implement them. They are just too hard and have too many points of failure. These solutions end up becoming the bane of our existence. We have to maintain them and fix bugs in them. Sure, we can be good citizens and use design patterns and well-documented architectures. Ultimately, however, we end up, time and time again, juggling big issues while trying to get a new piece of functionality into the system.
Among the XP practices are some techniques that will help us reduce the complexity of the problem.
The Genius Function
Ideally, we should find some way that we can all be geniuses. If we are all geniuses, we can always create simple solutions to all of our problems. Something we all know is that it is easy to create simple solutions to solve simple problems. So to become a genius, all we need to do is break down all of our problems into lots of smaller problems that are easy to solve.
Any problem that I estimate to take longer than four hours to solve is too big for me to feel comfortable with. I want to accomplish at least one thing in a day; if I accomplish more than that, I feel even better. This is a personal decision, but most people I have worked with aim for four hours or less. I have never worked with anyone1 who was comfortable with tasks that lasted more than six hours. If I get a task that I estimate will take longer than my maximum four-hour period, I break it down into several smaller tasks. If any of those tasks will take longer than four hours, I break those down again. Something that I have found interesting is that the most effective developers I know break down the majority of their tasks so that they require less than an hour to complete.
Example of Problem Breakdown
Let's see how this works, beginning with a trivial example before I lead you through a more complex problem breakdown.
Suppose the customer has asked us to develop a piece of software that emulates a calculator on the desktop. So this is our problem: develop a .NET Framework calculator. Easy. So how long will the development take? Do you know immediately? I don't, but I bet it will take longer than four hours, so I need to break down the problem. Here's a list of smaller problems:
Add functionAdd two numbers together
Subtract functionSubtract one number from another
Divide functionDivide one number by another
Multiply functionMultiply two numbers together
Can I give time estimates for each of these functions? I feel confident that I can, and I estimate between one and two hours for each function. Some people might ask, "Why so much?" After all, they know that I am an experienced developer and might think that I should be able to put a simple calculator together pretty quickly. I am estimating that this will take me up to a day to complete based on my experience. I am breaking the problem down into even smaller steps, and I will go through that process with you now for the add function.
Task |
Time to Complete |
Test for adding zeros |
15 minutes |
Test for adding negative numbers |
15 minutes |
Test for adding minimum numbers and maximum numbers (forcing overflows) |
15 minutes |
Test for adding positive numbers |
15 minutes |
User interface |
15 minutes |
Check code into source control and integrate with any existing solution |
5 minutes |
Total |
1 hour 20 minutes |
Notice that I emphasize writing tests. In the next chapter, you will learn why and how to write tests before the code. For now, it is important to understand that it gives me more focus on developing only what is required and nothing extra. These tests define the behavior expected of the object that will be developed.
Also notice that I am including the time it takes to write these tests, to develop the user interface, and integrate the code with a source control system. All these extra things take time that is often not accounted for by less-experienced developers and project managers. These extra things are often the reason so many software projects run late; developers too often fail to account for the "other stuff" that we need to do to write high-quality code.
With less-trivial problems, you will often find yourself asking some tricky questions, and this is where having contact with the customer becomes important. It is hard to break tasks down without being able to get answers to questions you have. Consider the preceding example. I have made an assumption that the calculator will deal with negative numbers. What if negative numbers are not permitted or required by the system? Having the customer present while doing this task breakdown will make this very apparent. The conversation in our eXtreme .NET team might go something like this:
Chris: Why are you testing for adding negative numbers? We don't want to add negative numbers!
Pete: Panic! What should happen if we get a negative number?
Chris: You should inform the user that negative numbers are not allowed.
Eddie: Okay, change that test to "Test for handling negative inputs, 10 minutes."
Remember one of the practices discussed in Chapter 1 was the whole team. Here is an example where having the customer as part of the team can make a difference. If you cannot get a customer to be present during a task breakdown session, try to get him or her on the phone or instant messenger. Failing that, try your manger or other developers. At least they may spot some mistakes or incorrect assumptions you have made before you actually commit them to code. You should e-mail your customer the results from each task breakdown session so that they can review them and change their minds or reset the direction.
We return to this scenario later on in this book to write code for some of these tasks.