This principle says a module should have precisely one reason to change.
Encapsulate sources of high uncertainty first. If it’s highly likely to change, make sure it can change separately from other things.
My previous post goes into more detail on this principle. To summarise:
- Don’t get carried away with this one and use it as an excuse to implement things “in case they’re needed in the future”.
- Do take a few moments to consider what might change in future, and shape the thing you’re about to implement to prepare for it
“Don’t lie with inheritance”.
I’d generalize to:
Reluctance to lie should be proportional to the difficulty of cleaning up that lie when its burden is too great.
From Wikipedia: “no client should be forced to depend on methods it does not use.“
The lower down in your dependency tree the interface is, the more important it is to segregate it.
Depend on abstractions (interfaces) rather than concretions.
Don’t hide your dependencies, use constructor injection of the interfaces your object needs. The topic of Dependency Injection frameworks often comes under this heading, but probably deserves a separate post. If you do use one, make sure that only the very highest layer of your application knows about it.