2012-01-13 6 views
7

다양한 유형의 페이지를 렌더링하기위한 간단한 서비스를 작성하려고합니다. Strategy pattern로 설계 될 것이다Symfony2의 전략 패턴

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

... : 기본 개념은 같은 것을 가지고있다. 페이지 유형은 render 메소드와 인터페이스를 구현하고 page.service은이를 호출합니다. 문제는 페이지 유형 클래스에서 Doctrine을 사용하고 싶습니다. 내 옵션은 무엇입니까? 나는이 클래스들 각각에 대한 서비스를 만드는 것을 피하고 싶다. 그게 가능한가? 컨테이너가 서비스없이 인식 할 수 있습니까? 미래에 어떤 페이지 유형은 교리 이외의 다른 것을 필요로 할 수도 있습니다. 따라서이 점을 명심해야합니다.

답변

1

PageType은 전략 클래스의 예입니다. 이 경우 page.service으로 종속성을 주입 할 수 있으므로 전략을 서비스로 정의 할 필요가 없습니다.

각 전략은 아마도 다른 개체에 따라 달라 지므로 ContainerAware을 만들 수 있다고 생각합니다. 여기가

// 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. 
} 

그래서 기본적으로 각각의 전략은 ContainerAware을 확장 할 수행하고 page.service이 컨테이너를 주입 할 방법 예입니다.

당신의 전략을 모두 같은 서비스에 의존하는 경우


편집, 나는 전체 컨테이너 대신를 주입 것입니다.

class MyPageService { 

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

     // do stuff 
    } 
} 
+0

주위를 지나칠 수 없습니다. 그의 목표가 교리를 요구한다면, 그는 교리 목표를위한 생성자에 매개 변수를 추가하여 그것을 요구해야한다. – meze

+0

@ meze 물론, 모든 전략이 서로 다른 의존성을 갖는다면 어떨까요? 이것이 유일한 방법 일 것입니다. 그러나 저는 개인적으로 모든 전략을 실제로 서비스로 정의 할 것입니다. – gilden

+0

및 전략 테스트 방법은 무엇입니까? 심포니없이 다른 프로젝트에서 재사용 할 수 있습니까? – meze

3

서비스가 원하는 서비스입니다. 문제의 특정 전략에 대한 종속성을 주입 할 수 있습니다. 그런 다음 특정 전략을 컨트롤러에 주입합니다 (런타임에 전략을 선택하는 동적 렌더러 일 수도 있음).

ContainerAware는 컨테이너의 서비스가 인 문제의 객체를 연결하는 아주 나쁜 습관입니다. 따라서 나는 그것을 피하는 것이 좋습니다.