I have some libraries in my 'framework' like routing, config, logger,... I want them to be independent of each other, like some of well known PHP frameworks make them.
I understand all the principles of loose coupling, but I have no clue how to follow both loose coupling and DRY principles. If I make routing library that config and logger, then I don't repeat myself, but if I want to use router on its own it won't work. Similarly if I write logging and config code into my routing library, I would repeat myself.
Loose coupling normally means that your components do not expect a concrete instance but just one instance that has a compatible interface.
Each collaborator can be replaced then with a different one of the same type. The code is not dependent on a concrete implementation of one of those any longer.
So:
Do not use:
global (static) functions
Foo:bar();
class based programming (passing a classname around)
stream_wrapper_register("var", "VariableStream");
global constants
if ( !defined('ABSPATH') )
define('ABSPATH', dirname(__FILE__) . '/');
But:
Use objects
$foo->bar();
Program against interfaces
public function __construct(LoggerInterface $logger) {
Unit-test with mocks
$logger = $this->getMock('LoggerInterface', array('log'));
See as well:
- Don't be STUPID: GRASP SOLID! (Dec 2011; by NikiC)