OO Design Principles In Practice

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.


What Is Codemanship?

Last year I created Codemanship as a vehicle for helping clients address one specific set of needs – the quality of their code. Agile has done a great job of addressing how software development’s managed and how teams can work together. It’s all good stuff, but sadly the great strides many companies have made in those directions have not been matched by great strides in the reliability and  maintainability of their code.

This presents those newly (or not-so-newly) Agile organisations with a problem. It’s always been understood that one of the keys to being responsive to change is to create code that’s easy to change.

The things we’ve learned through decades of experience are factors in how hard our code is to change are:

  • Readability – How easy it is to understand
  • Complexity – Code that’s complicated is harder to understand, harder to test and more likely to be wrong
  • Duplication – Duplicated logic (e.g., from copying and pasting code) has to be changed in multiple places, so multiply the overhead
  • Dependencies – If a change to one part of the software will break many other dependent parts of the software (the “ripple effect”), we’ll think twice about making that change
  • Test Assurance – If our tests don’t catch bugs, or if they take weeks or months to execute by hand, how will we know that the change we’re making hasn’t broken the software?

Codemanship focuses exclusively on these factors in the cost of changing our software, helping developers and teams to build up skills and habits that lead to code that’s more reliable, easier to understand, simpler, has less duplication, managed dependencies and much higher test assurance.

The disciplines that we find bring us these benefits most effectively on Agile and non-Agile projects are:

  • Test-driven Development – drive the evolution of our software one automated test at a time, creating code that does exactly (and only) what’s required and building a comprehensive suite of automated regression tests that can detect new bugs as soon as they’re introduced
  • Refactoring – continually work to keep the code clean (simple, readable, free of duplication and highly modular) by applying a well-defined set of safe, reversible code “transformations” and use automated regression tests to ensure nothing is broken
  • Object Oriented Design – apply key principles of good object oriented design to effectively manage the dependencies in our code and localise the potentially costly “ripple effect” when making changes
  • Continuous Integration & Delivery – frequently check in changes to the code to detect integration problems as early as possible and use automated build/test/deploy processes to ensure we always have a working system that can be deployed whenever the business requires, giving us more opportunities to learn from our users and evolve the software towards greater value more rapidly

I’ve been coaching software developers for the majority of my career, and over the years I’ve come to learn that the best way to teach someone practical skills like these is to give them as much practice as possible. This is why Codemanship’s approach to coaching and training is entirely hands-on and practice-based. Theory is useful, and I’ve read enough software theory to fill several Masters degrees, but Codemanship is about learning by doing. Beyond that simple philosophy, I hope what I do is more than just an exercise in self-reflection or theoretical instruction. Ultimately, if I’m teaching people to ride bicycles, I’m not going to get very far using PowerPoint slides, Panel Debate sessions or role-playing games.

Which is why everything I hope to cover with Codemanship will follow a very simple, practical mantra:

  1. Show people how I do it (e.g., post a screencast)
  2. Encourage them to have a go themselves (e.g., give them the source code)
  3. Give them tools to assess how well they’re doing it and where they might need to improve (e.g., good indicators of effective TDD and refactoring, useful techniques for assessing yourself while you do TDD/refactoring etc)

I wish it were more complicated than that. Because then I could probably write a book about it. But it’s actually really simple, and deliberately so.

The Codemanship training workshops are also designed to be more accessible. Publicly scheduled master classes will be run over weekends so that people don’t have to beg for time off work, and will be priced to bring them within reach of individuals taking responsibility for their own development and growth as software craftsmen, as well as small businesses and public sector and other non-profit organisations.

The Codemanship Academy has been running for a couple of years – since before I formed Codemanship Ltd, in fact – and has alumni from a number of client companies who have successfully completed long-term practice regimes in TDD and Refactoring, and who have proved their mettle through a gruelling one-day practical assessment (imagine a 5-6 hour driving test!) This was not a walk in the park for those who’ve done it, and they didn’t undertake it lightly.

The proof of the pudding is in the eating, of course. At one client site, analysis of their code on multiple projects before and after becoming Codemanship Alumni shows very significant improvements in test assurance and code quality. They also managed for the first time to deliver into production at a frequency this organisation had never achieved before. Continuous delivery is the Holy Grail of Agile Software Development, and our experiences are showing us that Codemanship can be an effective route to achieving it.

Imagine knowing that, at any time, you have software that works, that can be deployed and that can be easily changed based on the valuable lessons that deployment will teach you. This is what Codemanship is all about.

It’s an experiment, but an experiment that seems to be working. I hope that my gamble will pay off. I’m heartened by the increasing amount of interest I’ve been getting about Codemanship and the Academy, and software craftsmanship in general. My hope is that the era of clean, reliable code is finally upon us.