2016-08-07 4 views
-1

У меня есть следующий код.Вызов всех классов, реализующих интерфейс

Интерфейс Транспортное средство, которое имеет метод расчетаDistance.

Класс автомобиля реализует Автомобиль Класс велосипедов реализует Автомобиль Класс MOTORCYCLE реализует Автомобиль

То, что я хочу сделать следующий способ в мой контроллер, который вызывает каждый класс, который реализует транспортное средство и получить значения из calculateDistance.

Каким будет лучший способ/дизайн, чтобы достичь этого?

В данный момент я просто вызываю все классы, которые реализуют интерфейс Vehicle (через ReflectionClass) и перебирают их, чтобы вызвать этот метод.

+0

Дело в том, что с помощью designpatters вы можете «попробовать» несколько вещей. Речь идет не о попытках, а о том, что является самым правильным способом достижения этого. Я могу вставить все возможные вещи, которые я «пробовал», но это просто загромождает вопрос. – SnIpY

+2

Вы говорите: «У меня есть следующий код», но на самом деле не показывайте код ... вы просто описываете его. Отправьте код (последняя итерация). Также описывайте отклонения, которые вы отклонили, и почему вы их уволили. Это реальная проблема или это домашнее задание? Это довольно странное требование реального мира: «[...] метод в моем контроллере, который вызывает каждый класс, который реализует Vehicle, и получает значения from calculateDistance». Зачем вам это нужно? т.е.: что вы * на самом деле должны достичь в качестве конечного результата? –

ответ

0

Лучший способ - реализовать CompilerPass. Вот example. Итак, создайте класс реестра (TransportChain в этом примере), интерфейс и все классы, реализующие этот интерфейс, определите их как службы и дайте им имя тега. После этого вы можете вызвать эту службу реестра в своем действии и вызвать ваш метод по каждой службе.

Простой пример:

интерфейс

interface SomeInterface { 
    public function doSomething(); 
} 

Сервис 1:

class First implement SomeInterface { 
    public function doSomething() { 
     // do smth 
    } 
} 

Service 2:

class Second implement SomeInterface { 
    public function doSomething() { 
     // do smth 
    } 
} 

класс реестра:

class MyRegistry 
{ 
    private $services = []; 

    public function addMyService($service) 
    { 
     $this->services[] = $service; 
    } 

    public function all() 
    { 
     return $this->services; 
    } 
} 

CompilerPass:

... 

    $myServices = $container->findTaggedServiceIds('my_tag'); 

    if (empty($myServices)) { 
     return; 
    } 

    $registry = $container->getDefinition('my_registry'); 

    foreach ($myServices as $key => $myService) { 
     $registry->addMethodCall('add', [new Reference($key)]); 
    } 

    ... 

После clearign кэша, вы можете вызвать их в действии:

... 

foreach ($this->get('my_registry')->all() as $myService) { 
    $myService->doSomething(); 
} 

... 

Все другие вещи, как декларирование услуги, дать им имя тега, регистрации ваш компилятор был записан here.

Смежные вопросы