Artima.com has published Part VI of an interview with Martin Fowler in which he discusses balancing maintainability and efficiency, creating tunable software, the role of patterns, and the Agile Software Manifesto.
Here's an excerpt:
So you could make a performance optimization in one VM, and then bring in Hotspot, and it will actually slow Hotspot down. You've got to be very wary of that. Object pooling is a good example. A lot of people are very enamored with object pooling, yet half the time people are not measuring to that to find out whether object pooling is any good. Object pooling was very important in the early days of Java, because garbage collection wasn't terribly good. When you've got generational garbage collection, object pooling becomes a lot less effective, because short-lived objects can be collected very cheaply. It's the long-lived objects, such as ones you might pool, that are expensive to garbage collect.
So the rules keep changing. That's why you've got to be very careful to profile. If you think you can predict from the source code what the machine is doing, you've got no chance. When you're in a world of optimizing compilers and VMs, you have to profile, because the compilers and VMs are doing things that you can't even imagine. So don't predict, just measure.
Here's an excerpt:
The thing I like about taking small steps and writing tests first is that it gives me a simple to do list of the things I've got to do. At each end point I have a certain amount of closure. I say, OK, this stuff works. Check it in. It's all there. It does what it does and it does it correctly.There's an impossible-to-express quality about test- first design that gives you a sense of unhurriedness. You are actually moving very quickly, but there's an unhurriedness because you are creating little micro-goals for yourself and satisfying them. At each point you know you are doing one micro-goal piece of work, and it's done when the test passes. That is a very calming thing. It reduces the scope of what you have to think about. You don't have to think about everything you have to do in the class. You just have to think about one little piece of responsibility. You make that work and then you refactor it so everything is very nicely designed. Then you add in the next piece of responsibility. I previously used the kind of approach you describe. I'd ask, "What's the interface of this?" I've now switched and I much more prefer incremental design.
Here's an excerpt:
The cost of flexibility is complexity. Every time you put extra stuff into your code to make it more flexible, you are usually adding more complexity. If your guess about the flexibility needs of your software is correct, then you are ahead of the game. You've gained. But if you get it wrong, you've only added complexity that makes it more difficult to change your software. You're obviously not getting the payback.It's not hard to guess wrong about flexibility needs. You can guess wrong if requirements change. What you think is a requirement for flexibility now may go away or change in the future. You can also guess wrong if you put extra code into the program to improve flexibility but you don't get it quite right. You get more complexity without getting the flexibility you were after.
The alternative is to use the XP approach and not put the flexibility in at all. XP says, since most of the time we get it wrong, just don't put the flexibility in there. Now if you can't evolve your design safely, then that is a foolish route to take. But if you can evolve your design safely, it becomes quite a nice approach. In fact it becomes a self-reinforcing approach. If you strive to keep your design as simple as possible by avoiding speculative flexibility, then it's easier to change the code because you have less complication to deal with. The code is easier to understand and easier to change. As a result, you can make changes much more quickly.
