2016-08-07 92 views
-1

Ich habe den folgenden Code an Ort und Stelle.Rufen Sie alle Klassen, die eine Schnittstelle implementieren

Interface Vehicle, das über eine Methode calculateDistance verfügt.

Klasse Car implementiert Fahrzeug Klasse Fahrrad implementiert Fahrzeug Klasse Motorrad-Fahrzeug implementiert

Was will ich als nächstes zu tun ist ein Verfahren in meinem Controller ist, dass jede Klasse aufruft, das Fahrzeug implementiert und die Werte von calculateDistance erhalten.

Was wäre der beste Weg/Design-Muster, um dies zu erreichen?

In diesem Moment rufe ich nur alle Klassen auf, die das Interface Vehicle (über ReflectionClass) implementieren und durchlaufen sie, um diese Methode aufzurufen.

+0

Die Sache ist, dass Sie mit Designpattern mehrere Dinge ausprobieren können. Es geht nicht darum, es zu versuchen, sondern darum, wie dies am besten erreicht werden kann. Ich kann alle möglichen Dinge einfügen, die ich "versucht" habe, aber das würde die Frage nur verwirren. – SnIpY

+2

Sie sagen "Ich habe den folgenden Code", aber dann zeigen Sie nicht wirklich den Code ... Sie beschreiben es nur irgendwie. Veröffentlichen Sie den Code (die letzte Iteration). Beschreiben Sie auch die Abweichungen, die Sie abgewiesen haben, und warum Sie sie abgelehnt haben. Ist das ein Problem der realen Welt oder sind es Hausaufgaben? Das ist eine ziemlich seltsame Anforderung der realen Welt: "[...] eine Methode in meinem Controller, die jede Klasse aufruft, die Vehicle implementiert und die Werte von calculateDistance abruft". Warum musst du das tun? ie: Was müssen Sie eigentlich als Endergebnis erreichen? –

Antwort

0

Der beste Weg ist, CompilerPass zu implementieren. Hier ist ein example. Erstellen Sie also eine Registrierungsklasse (TransportChain Klasse in diesem Beispiel), eine Schnittstelle und alle Klassen, die diese Schnittstelle implementieren, definieren Sie sie als Dienste und geben Sie ihnen den Namen des Tags. Anschließend können Sie diesen Registrierungsdienst in Ihrer Aktion aufrufen und die gewünschte Methode von jedem Dienst aufrufen.

Grund Beispiel:

Schnittstelle

interface SomeInterface { 
    public function doSomething(); 
} 

Service 1:

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

Service 2:

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

Registry-Klasse:

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)]); 
    } 

    ... 

Nach clearign den Cache, können Sie sie in Ihre Aktion nennen:

... 

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

... 

Das ganze andere Sachen, wie Dienstleistungen zu erklären, geben ihnen Namen markieren, Registrierung Ihr Compiler Pass wurde here geschrieben.