Of late I've been really interested to understand how practitioners are designing their OO systems. I've paired with various people during my Avatars of TDD experiment. What I have seen so far is
- From the problem statement, single out all the nouns and verbs - end up with a lot of useless objects which lack clear responsibility. Also can argue for ever whether a method belongs on this object or another (Ex: Should Doctor class have a giveShot method or should Patient class have a takeShot method)
- Focus on collaborations and responsibility - can get overwhelming when you look at a large system. Without tests, they can be very confusing to a 3rd person. Without design metaphors and design patterns one cannot easily understand these systems.
- Try to model the real world - Strict modeling of the real world leads to systems as complicated as real world. Also they seem to be rigid, because they only reflect today's realities, but not necessarily tomorrows.
- Test Driven Design with Spiking - If the developer does not understand basic design principles and OO concepts, this can lead to big ball of mud. Spiking helps in flushing out the overall approach, while Unit and Acceptance Tests really help in validating the design and creating safety net around the code for easy refactoring.
- Prototyping followed by Design elaboration phase - one or more quick prototypes helps understand and learn about the system. Based on this learning, developers can choose any of the above design approaches. Big trouble when the prototype is not thrown away and is converted into production code.
- Cow boy coding : Design what? Just type it in notepad and pray it will all work.
I'm interested to know if people see other approaches.
I would also be interested to pair with people on the Avatars of TDD experiment.