2012-01-13 18 views
7

Estoy intentando crear un servicio simple para representar varios tipos de páginas. concepto básico es tener algo como:Patrón de estrategia en Symfony2

$somePageType = new PageType(...); 
$this->get('page.service')->render($somePagetype); 

... que se ha diseñado como Strategy pattern. Los tipos de página implementarían la interfaz con el método render y lo llamarían page.service. El problema es que me gustaría usar Doctrine en las clases de tipo de página. ¿Cuáles son mis opciones aquí? Me gustaría evitar crear un servicio para cada una de estas clases. ¿Es eso posible? ¿Es posible hacerlos conscientes de los contenedores sin ser servicios? Posiblemente, en el futuro, algún tipo de página podría necesitar algo más que solo Doctrine, así que también debo tenerlo en cuenta.

Respuesta

1

Supongo que PageType es un ejemplo de una clase de estrategia. En ese caso, podría inyectar las dependencias por el page.service y no necesitaría definir las estrategias como servicios.

Cada estrategia probablemente depende de diferentes objetos y por lo tanto, supongo que podría hacerlos ContainerAware. He aquí un ejemplo de cómo hacerlo

// This is the page.service class 
class MyPageService { 

    public function render(PageTypeInterface $page_type) { 
     $page_type->setContainer($this->container); 

     // do stuff 
    } 
} 

// This is the type strategy 
class MyStrategyType extends ContainerAware implements PageTypeInterface { 
    // you can access the container after MyPageService has injected it. 
} 

Así que, básicamente, cada estrategia se extendería ContainerAware y la page.service inyectaría el contenedor.


EDITAR

Si todas sus estrategias dependen de los mismos servicios, me inyectarlos en lugar de todo el recipiente.

class MyPageService { 

    public function render(PageTypeInterface $page_type) { 
     $page_type->setService($this->container->get('my_service')); 

     // do stuff 
    } 
} 
+0

Eso no es bueno para pasar el contenedor. Si su objeto requiere doctrina, debe requerirlo agregando un parámetro en constructor para doctrine object. – meze

+0

@meze por supuesto, pero ¿y si cada estrategia tiene dependencias diferentes? Esta sería la única manera. Sin embargo, definiría personalmente todas las estrategias como servicios en realidad. – gilden

+0

y cómo probarías tus estrategias? reutilizar en otro proyecto sin Symfony? – meze

3

Los servicios son exactamente lo que usted desea aquí. Ser capaz de inyectar las dependencias para la estrategia particular en cuestión. Luego, inyectando la estrategia particular en el controlador (también podría ser un procesador dinámico que elige la estrategia en tiempo de ejecución).

ContainerAware es una muy mala práctica, se acopla el objeto en cuestión a todos de los servicios en el contenedor. Por lo tanto, recomiendo evitarlo.

Cuestiones relacionadas