Software development can sometimes be very counterintuitive. For example, when people started building larger software systems halfway through the last century one of the things they discovered was that changing existing software is often far more difficult and error prone than building new software. Most developers rediscover this somewhere in their first year of being a professional developer. They start out with a new project and as time goes by changes start taking more and more time, this can be very hard to explain to a client and usually we don’t until we get completely stuck and tell the client we need to start from scratch. I think this practice has been responsible for most of the bad reputation software development has.
So if changing software is such a hard thing to do we just have to do things right from the beginning. Analyze all requirements the client could ever have, make a design that incorporates all those requirements and then build that, this way we should never have to change anything. Sounds like a great plan but there are three things that make this quite impossible. Clients, stupid programmers and the rest of the world.
First of all clients don’t know what they want. It seems like I’m just trying to shift blame away from developers like me but I’m not. This is just a fact we have to deal with in our profession. Clients are not omniscient. They learn during a project and learning makes them change their mind. Of course there are ways to make sure clients don’t do silly things like this. You can spend more time doing requirements studies so they have a chance to change their mind before we start building or we can write everything down in big contracts so clients aren't allowed to change their mind anymore.
But then we encounter our next hurdle, stupid programmers. See, now I’m laying blame directly at our own feet. Programmers aren’t omniscient either. When you ask them to design a system they will make mistakes. The bigger the system the more mistakes. And most of these mistakes will only show up once you’ve built the system, meaning you have to change the system and we didn’t want to do that. Of course there’s an easy solution for this. You don’t let developers design the system anymore. You’ve got architects for that, they’re easy to find, they live in ivory towers.
So now you’ve spent a year creating the best requirements. Your architects have created a bulletproof design, you can now safely build your system right? Well no. Now you’ve got the real world to contend with. And it changes too.
I think we can safely conclude that resisting change isn’t a solution for our problems. Agile methodologies acknowledge that fact. Agile tells us to embrace change. But how do we make sure our software doesn’t make us regret this? We need to architect our software to embrace change too. Instead of going to around the problem like we used to do we need to get to the bottom of it and eliminate it from our software.
But how do you architect software to be changeable? Well this is another counterintuitive aspect of software engineering. In other engineering practices we have to contend with natural laws that constrain what we do. In structural engineering gravity is a big constraint. When you want to be flexible you build bigger foundations. In electrical engineering Ohm’s law is a constraint, so when you want to be flexible there you build in bigger cooling fins and more powerful power supplies. Software engineering is different in this aspect. Our main concern is complexity so preparing for change by over dimensioning your foundations will only work against you, you’re only making your software more complex, that will not help you fight complexity.
An agile architect will always go for simplicity. Do the simplest thing that will actually work, don't build things you’re not sure you’ll need. Keep responsibilities separated and abstract away everything.