I’m running the first of the newly redesigned OO design principles workshops this weekend in London (and a 1-day version on Sept 16th at Bletchley Park – places still available and all proceeds to charity).
OO design principles run the risk of being a bit too abstract and theoretical, and the major challenge has been to reframe my original training to be as hands-on and practical as possible. Indeed, this may be where so many OO courses and books have faltered.
A particular challenge is to apply the principles on a day-to-day basis. How does S.O.L.I.D. translate into coding habits?
Well, I’ve had a stab.
First of all, I’ve compressed all of the theory into 4 “golden rules” of OO design:
1. Minimise Dependencies – if we write less code, there’ll be less dependencies overall. Doing the simplest thing possible, and refactoring to remove duplication help keep our code small and that means less spaghetti. I’m not talking about classes, per se, at this level. I’m talking about things that refer to otehr things. Fields, variable, methods and so on. I’m talking about implementation.
2. Localise Dependencies - Of course, we have to write some code, which means there have to be some dependencies. But wherever possible, things that depend on each other need to be bound together inside methods, classes and packages. For example, methods should be in the same classes as the fields they access. We want as few dependencies crssoing those boundaries as possible.
3. Stabilise Dependencies – Again, we can’t avoid having dependencies cross class/package boundaries, ir there’d be no possibility of modularisation and reuse, and we’d end up with one huge method in one huge class. But where dependencies can’t be localised, we must strive to depend on things that are less likely to change. Very often that means favouring dependencies on things that are already heavily depended-upon, since the impact and cost of changing them makes changing them prohibitively expensive. Take VHS vs. Betamax, for example. As VHS became increasingly popular with consumers and manufacturers, any company looking to make a VCR or release their film on video would have been wisest to back the dominant standard. If 90% of VCRs in the world are VHS, changing the format or shape of the VHS cassette would have had a massive impact, hence it was a safe bet the format would not change.
4. Abstract Dependencies - With VHS again, what would hve been the upshot if the standard required a specific image/video signal format in all players? Stereo sound might not have been introduced to video. Nor widescreen when it finally came. The VHS standard was not prescriptive enough that future enhancements and extensions were blocked. If I had a widescreen TV with stereo sound and a VCR that could play widescreen video with stereo sound, I could enjoy my films in widescreen with stereo sound. But someone with an older TV and VCR could still play the cassette and watch it in 4:3 and mono. Strive for the same thing with OO design. The things that we depend on should be less prescriptive the more we depend on them, and easier to extend and substitute (like those Hi8 video cassette adaptors we used to use to play our home movies in VHS machines).
And I’ve tried (oh boy, have I tried?!) to boil down OO design into a set of habits just as I’ve done for TDD and Refactoring on my other courses and client coaching programs:
- Write the simplest code possible
- Refactor mercilessly to remove duplication
- Put the behaviour where the data is
- Objects should be born with their collaborators (dependency injection)
- Ensure classes (and methods) do one distinct thing
- Restrict interactions to a small number of direct collaborators
- Favour fewer, higher-level interactions
- Introduce abstractions through refactoring
- Favour dependencies on abstractions
- Test that subclasses satisfy super-class contracts
- Package dependent classes together as much as possible
- Continuously analyse and manage dependencies
- Ensure your design makes sense in the application domain!
The idea is that, on a day-to-day basis, these are the habits you practice and you can see whether someone is or isn’t doing them while they’re coding. And, I think – based on experience, if you do these habitually you should end up with code that is all good and healthy from an OO/dependencies point of view.
This was always the missing piece of the jigsaw. I’ve got lots of experience explaining OO principles to developers, but the question at the end has alays been “great, now what do you want me to do differently?”
The OO workshop goes into the practical detail and explores these principles and habits through a series of code examples. Indeed, it’s mostly coding/refactoring. Which is something of a breakthrough, I’m pleased to say.