These past few years, I feel increasingly that most components can avoid difficult dependencies by adhering to one simple principle: each component should stick to a single responsibility.
To use a practical example, think about a component that sends e-mail via SMTP – this is the kind of thing where you’re typically going to want some kind of diagnostic facility when it’s running in production. So many people will simply add a $debug flag to the class, and this will toggle some internal logging feature on or off.
The problem with that is, logging diagnostic messages has nothing to do with the sending e-mail – and because logging can be done in 100 different ways, this introduces scope creep and eventually multiple different logging-methods and some way to toggle them, which is way beyond what an e-mail component should do.
Modern PHP has closures, so we can now solve this by simply adding a callback property (e.g. $onLog) to the class – and suddenly, all the SMTP class needs to knows about logging is that messages exist. Everything else can be delegated to a programmer, who can choose to plug in his favorite logger, test-framework, Twitter API, a simple echo-statement during development, or whatever madness you see fit.
Sure, turning on logging now is a bit more work than just raising a boolean flag – but I think we all need to get more comfortable writing a couple of lines in a closure and think of it as “configuration”, even if it is code. It’ll make our lives easier in the long run.
(in reply to: "On Libraries and Dependencies" by Bernhard Schussek)