Набросал класс управления зависимостями в приложении
/**
* Class DependencyManager
*/
class DependencyManager {
/**
* @var array of dependencies
*/
public $dependencies;
/**
* DependencyManager constructor
*/
public function __construct() {
$this->dependencies = [
[
'class' => 'SomeClass',
'dependencies' => [
'DependentedClass', 'SecondDependentedClass'
]
]
];
}
/**
* @param $class
* @return null OR Dependencies of class
*/
public function checkDependencies($class) {
$dependenciesByClass = null;
foreach( $this->dependencies as $data ) {
if($data['class'] === $class) {
$dependenciesByClass = $data['dependencies'];
break;
}
}
return $dependenciesByClass;
}
}
/**
* Class DependentedClass
*/
class DependentedClass {
public $variable = 'this text placed in DependentedClass <br />';
}
/**
* Class SecondDependentedClass
*/
class SecondDependentedClass {
public $moreVariable = 'this text placed in SecondDependentedClass';
}
/**
* Class SomeClass
* class for example
* It is dependent on other classes
*/
class SomeClass {
public $varInDependentedClass;
public $varInSecondDependentedClass;
public function __construct(DependentedClass $dependentedClass, SecondDependentedClass $secondDependentedClass) {
$this->varInDependentedClass = $dependentedClass->variable;
$this->varInSecondDependentedClass = $secondDependentedClass->moreVariable;
}
}
/**
* Class Loader
* This class creates an instance of any class
*/
class Loader {
public $className;
public $dependencyManager;
/**
* Loader constructor.
* @param DependencyManager $dependencyManager
*/
public function __construct(DependencyManager $dependencyManager) {
$this->dependencyManager = $dependencyManager;
}
/**
* @return null|object
* this method loads classes
*/
public function loadClass() {
$dependencies = null;
$arrayObjects = null;
$reflection = null;
$instance = null;
$this->className = 'SomeClass';
if( !is_null($this->className) ) {
$dependencies = $this->dependencyManager->checkDependencies($this->className);
if( !is_null($dependencies) ) {
for($i = 0; $i < count($dependencies); $i++) {
$arrayObjects[$i] = new $dependencies[$i];
}
$reflection = new ReflectionClass( $this->className );
$instance = $reflection->newInstanceArgs($arrayObjects);
} else {
$instance = new $this->className;
}
}
return $instance;
}
}
Usage:$loader = new Loader( new DependencyManager() );
var_dump( $loader->loadClass() );
/*
* var_dump() results:
* object(SomeClass)#6
* (2) {
* ["varInDependentedClass"] => string(43) "this text placed in DependentedClass"
* ["varInSecondDependentedClass"] => string(42) "this text placed in SecondDependentedClass"
* }
*/
Очень удобная вещь, теперь можно по частям тестировать приложение.
НО
Что меня смущает:
1. То что нужно вручную собирать массив зависимостей ( метод DependencyManager::__construct() );
2. Что возможно я что то упустил либо нагородил, например формирование массива объектов-зависимостей ( метод Loader::loadClass() )
UPDATE
Еще пришла идея в классы с зависимостями передавать в аргументах интерфейсы, а не объекты.
Прошу заметить что это не полностью рабочий вариант, и прошу дать совет по основной идее работы класса, а не по пропущенным проверкам и тд. Многие моменты максимально облегчены для быстрого понимания