I realised my last post was a bit negative, so I thought I’d do a quick one with my 2c about what you should do instead of following patterns. There obviously needs to be a way by which you can judge how good code is, a “design principle” if you like.
In my world, there is only one design principle, from which all others can be derived:
My definition of encapsulation is minimising the amount of code that has to know about a particular concept. “Concept”, here, is a very broad term, which can mean anything from
- a single rule about the behaviour of a program (some might call a piece of business logic)
- the existence of another component of the program, or a library
- the use of particular language features (threading is a good example here, I’ll blog about how one day)
- a use case of the program
I’d say that code “knows about” a concept if it could ever interact with its behaviour. So if two methods in a class obviously use a concept, the rest of the class “knows about” it, because one day they might interact with it. Badly designed classes can leak interaction possibility, obviously we need to try to avoid that.
Optimising a single measure, that sounds easy, right? Absolutely not! Like a good game of whack-a-mole, reducing the scope of one concept tends to increase the scope of another, and only finger-in-the-air style judgement can get you anywhere near the best overall.
Like I say, all other design principles stem from encapsulation:
- Concise code reduces the amount of code the concepts in it are spread over (over-architecting can often reduce encapsultation in this way)
- Loosely coupled code splits concepts so less of them have to be in both places
- Repeated code obviously increases the number of places a concept is known about
I’m sure there are more. Can you think of any principles you follow, but don’t come under encapsulation?