DISCLAIMER: For the agilists reading this post, there is nothing new here. I just hear a lot of misconceptions around terms like YAGNI and wanted to provide my own take on things.
YAGNI is an acronym for "you ain’t gonna need it". You often hear it bandied about agile shops. One developer suggests an over-architected solution and the other cries out YAGNI. For example:
Dev#1: We can transfer that file using BizTalk!
Dev#2: YAGNI. We can download it using HttpWebRequest.
I’m not knocking BizTalk here. My point is that if all you need to do is transfer a file from point A to point B, BizTalk is an awfully complicated and expensive way to do it.
Many agile critics see YAGNI as an excuse for developers to do stupid things. Critics claim that YAGNI encourages developers to hard-code connection strings and other silliness. "In development, you’re not going to need to change the connection string. So by the YAGNI principle, you should hard-code your connection strings. Isn’t agile stupid?" YAGNI is a principle like any other and should be applied intelligently. It’s about keeping simple problems simple. It’s about the right tools for the right job – don’t try to drive a finishing nail with a sledgehammer. Too often we as an industry implement "enterprise solutions" to solve otherwise trivial problems.
YAGNI isn’t an excuse to be sloppy with your architecture. If you’re building the next hot social bookmarking application, it better scale. You better design with caching, distribution, load-balancing, etc. in mind. I would want some architectural spikes demonstrating acceptable performance at high user loads. Similarly if you’re developing an internal application to be used by 10 users, I would bet that you don’t need the complexity of a load-balanced web farm, distributed middle-tier cache infrastructure, and a clustered database. YAGNI is about choosing the appropriate amount of complexity for the problem at hand.
YAGNI is about building software at the last responsible moment. The "responsible" part is key. You can’t slap an asynchronous architecture in after the fact. You need to design that in up front. At the same time you should avoid speculative generalization. Solve the problems at hand with a responsible eye toward future requirements. Keep yourself lean and nimble enough to respond to those future requirements, but don’t build them "just in case we need them". What you will need in the future seldom has any resemblance to what you might build now. Even worse, unused features add complexity and rigidity to a codebase. You’re actually worse off than if you didn’t have those features at all! Keeping your architecture simple, lean, and nimble requires a lot of discipline.
So next time someone suggests using a SOA-based ESB to integrate the disparate workflows in the document lifecycle, ask yourself whether a wiki couldn’t work just as well. :^)