Design with real-life experience in mind

Real-life requirements are strokes of a bigger landscape. Designing for a partial set of requirements is bad practice because you do not have the photo where your application is expected to fit. In GoF patterns jargon we are talking about the forces thing that prevents any pattern from being applicable to Each and Every Case.

Things are much easier when you are developing customized software, but with products there are many more decisions to make. The old habit of designing standards from scratch is stepping aside for experience-driven architecture, where existing use cases are the basement of further design. Even doing so, you will not get the whole picture until users start flooding your system, giving you feedback about how well your system fits The Real Thing and how many cases you left unresolved.

My way (well, sorta)

When talking about products, I follow a very simple design process. Hey, I am not saying this is top-notch approach to product design or anything, just "there are many like it, but this one is mine".

First of all, I always start refusing to code. If you don't yet own a copy of Getting Real, I cannot recommend it enough (even more if you live in Europe, since they only charge you 2 € for shipping). From the book,

"Each time you say yes to a feature, you're adopting a child. You have to take your baby through a whole chain of events (e.g. design, implementation, testing, etc.) [...] Don't be a yes-man." - Getting Real, 37signals

I like to call that suicide requirements: every time a customer calls with a feature request, first try to apply standard YAGNI judo techniques, or give a workaround with existing features. When the same request appears frequently, accept the defeat and add it to the schedule. You lost.

“…the cost of adding a feature isn't just the time it takes to code it. The cost also includes the addition of an obstacle to future expansion [...] The trick is to pick the features that don't fight each other.” - John Carmack.

Do NOT develop anything without a real use case first (more than one would be better, but don't be picky). By doing this you are buying some certainty of avoiding features never needed by real life, and as a side effect helps prioritizing features and bugfixes.

Delay the implementation as much as a reasonable schedule permits. Start talking to your Java hens, giving them time to lay the idea that will save the day, improve sexual life and alleviate global warming (or not). I cannot stress this enough: I have lost entire months for not giving it enough pencil time.

When implementation time comes, apply the best brewed design and cross fingers; if you are lucky, you won't have to change it THAT much.