Есть классы ModuleA, ModuleB, ModuleC, ... . Каждый со своим набором методов:
abstract class AbstractModule { /* ... */ }
class ModuleA extends AbstractModule
{
public function a1() { /* ... */ }
}
class ModuleB extends AbstractModule
{
public function b1() { /* ... */ }
public function b2() { /* ... */ }
}
class ModuleC extends AbstractModule
{
public function c1() { /* ... */ }
public function c2() { /* ... */ }
public function c3() { /* ... */ }
}
Имеется ещё один класс:
class Boss
{
/** @var AbstractModule[] **/
protected $_modules;
public function __construct(array $modules)
{
$this->_modules = $modules;
}
/**
* Последовательно запускает выполнение всех методы всех модулей с соблюдением условий.
*/
public function process()
{
// ...
}
}
Требуется реализовать метод process (с внесением необходимых изменений в классы ModuleA, ModuleB, ModuleC и AbstractModule), который выполнит все методы всех модулей из массива $this->_modules с соблюдением некоторых условий, например:
- Если в массиве $this->_modules имеется модуль ModuleA, то его метод ModuleA::a1 должен быть выполнен первым.
- Если в массиве $this->_modules имеется модули ModuleB и ModuleC, то метод ModuleB::b2 должен быть выполнен не раньше, чем ModuleC::c3, но и не позже, чем ModuleC::c2.
- Если в массиве $this->_modules имеется модуль ModuleB, то метод ModuleB::b1 должен быть выполнен не раньше, чем ModuleB::b2.
Для данных условий методы могут быть выполнены в следующем порядке:
ModuleA::a1()
ModuleC::c1()
ModuleC::c3()
ModuleB::b2()
ModuleB::b1()
ModuleC::c2()
Сами условия могут быть описаны внутри модулей, но никак не внутри класса Boss, т. к. могут появиться новые модули, о которых классу Boss ничего не известно, кроме того, что они наследуют AbstractModule.
Как бы Вы реализовали подобное?