• No results found

What Is Simplest?

So, the definition of the best design is the simplest design that runs all the test cases. The effectiveness of this definition turns on, what do we mean by simplest?

Is the simplest design the one with the fewest classes? This would lead to objects that were too big to be effective. Is the simplest design the one with the fewest methods? This would lead to big methods and duplication. Is the simplest design the one with the fewest lines of code? This would lead to compression for compression's sake and a loss of communication.

Here is what I mean by simplest—four constraints, in priority order.

1.

The system (code and tests together) must communicate everything you want to communicate.

Only Once rule).

3.

The system should have the fewest possible classes.

4.

The system should have the fewest possible methods.

The purpose of the design of the system is, first, to communicate the intent of the programmers and, second, to provide a place for the logic of the system to live. The constraints above provide a framework within which to satisfy these two requirements.

If you view the design as a communication medium, then you will have objects or methods for every important concept. You will choose the names of classes and methods to work together. Constrained as you are to communicate, then you must find a way to eliminate all the duplicated logic in the system. This is the hardest part of design for me, because you first have to find the duplication, and then you have to find a way to eliminate it. Eliminating duplication naturally leads you to create lots of little objects and lots of little methods, because otherwise there will inevitably be duplication.

But you don't just create new objects or methods for the fun of it. If you ever find yourself with a class that does nothing and communicates nothing or a method that does nothing and

communicates nothing, then you delete it.

Another way of looking at this process is as erasure. You have a system that runs the test cases. You delete everything that doesn't have a purpose—either a communication purpose or a

computational purpose. What you are left with is the simplest design that could possibly work.

How Could This Work?

The traditional strategy for reducing the cost of software over time is to reduce the probability and cost of rework. XP goes exactly backwards. Rather than reduce the frequency of rework, XP revels in rework. A day without refactoring is like a day without sunshine. How could this possibly cost less?

The key is that risk is money just as much as time is money. If you put in a design feature today and you use it tomorrow, you win, because you pay less to put it in today. Chapter 3, Economics of Software Development, however, suggests that this evaluation is not complete. If there is enough uncertainty, the value of the option of waiting is high enough that you would be better off waiting.

Design isn't free. Another aspect of this situation is that when you put more design in today, you increase the overhead of the system. There is more to test, more to understand, more to explain. So every day you don't just pay interest on the money you spent, you also pay a little design tax. With this in mind, the difference in today's investment and tomorrow's investment can be much greater and it is still a good idea to design tomorrow for tomorrow's problems.

As if this weren't enough, the killer is risk. As the Economics of Software Development pointed out, you can't just evaluate the cost of something that happens tomorrow. You also have to evaluate the probability of it happening. Now, I love to guess and be right just as much as anybody, but what I discovered when I started paying attention was that I didn't guess right nearly as often as I thought. Often the fabulous design that I created a year ago had nearly no correct guesses. I had to rework every bit of the design before I was done, sometimes two or three times.

So, the cost of making a design decision today is the cost of making the decision plus the interest we pay on that money plus the inertia it adds to the system. The benefit of making a design decision today is the expected value of the decision being profitably used in the future.

If the cost of today's decision is high, and the probability of its being right is low, and the probability of knowing a better way tomorrow is high, and the cost of putting in the design tomorrow is low, then we can conclude that we should never make a design decision today if we don't need it today. In fact, that is what XP concludes. "Sufficient to the day are the troubles thereof."

Now, several factors can make the above evaluation null and void. If the cost of making the change tomorrow is very much higher, then we should make the decision today on the off chance that we are right. If the inertia of the design is low enough (for example, you have really, really smart people), then the benefits of just-in-time design are less. If you are a really, really good guesser, then you could go ahead and design everything today. For the rest of us, however, I don't see any alternative to the conclusion that today's design should be done today and tomorrow's design should be done tomorrow.