엔티티, 리포지토리 및 서비스 레이어가있는 도메인 모델이 잘 정의 된 MVC 응용 프로그램이 있습니다.다음 예에서 Service Locator가 안티 패턴 인 이유는 무엇입니까?
내 컨트롤러 내부에서 서비스 클래스를 인스턴스화하지 않아도되고 내 컨트롤러에 맞지 않는 논리를 사용하면, Service Locator 일종의 역할을하는 도우미를 만들었지 만 조금 읽은 후에도 깨달았습니다. 많은 DEVS :
- http://blog.tfnico.com/2011/04/dreaded-service-locator-pattern.html
- http://blog.ploeh.dk/2010/02/03/ServiceLocatorIsAnAntiPattern.aspx
- http://underground.infovark.com/2010/06/18/the-service-locator-pattern-is-the-new-global-variable/
- http://www.andyfrench.info/2011/05/service-locator-anti-pattern_17.html
서비스 탐지기가 실제로 안티 패턴이라고 말하면됩니다. 그러나 제 구현은 반 패턴이 아니라고 생각합니다.
서비스 로케이터를 anti-pattern으로 생각하는 이유는 종속성을 숨기기 때문입니다. 그러나 Entity Manager 만 종속성을 주입합니다 (이 종속성은 변경되지 않습니다). 서비스 인터페이스 (service interface))를 사용하여 서비스 로케이터 (Service Locator)를 인스턴스화합니다. 전면 컨트롤러와 동작 도우미 등록
<?php
namespace App\Controller\Action\Helper;
use Zend_Controller_Action_Helper_Abstract as Helper,
Doctrine\ORM\EntityManager;
/**
* Service Locator Helper
* @author JCM
*/
class Service extends Helper {
/**
* The actual EntityManager
* @var \Doctrine\ORM\EntityManager
*/
private $entityManager;
/**
* Services Namespace
* @var string
*/
private $ns;
/**
* @param EntityManager $entityManager
* @param string $ns The namespace where to find the services
*/
public function __construct(EntityManager $entityManager, $ns)
{
$this->entityManager = $entityManager;
$this->ns = $ns;
}
/**
* @param string $serviceName
* @param array $options
* @param string $ns
*/
public function direct($serviceName, array $options = array(), $ns = null)
{
$ns = ((!$ns) ? $this->ns : $ns) . '\\';
$class = $ns . $serviceName;
return new $class($this->entityManager, $options);
}
/**
* @param EntityManager $entityManager
*/
public function setEntityManager(EntityManager $entityManager)
{
$this->entityManager = $entityManager;
}
/**
* @return \Doctrine\ORM\EntityManager
*/
public function getEntityManager()
{
return $this->entityManager;
}
/**
* @param string $name
*/
public function __get($name)
{
return $this->direct($name);
}
}
: 여기
내 코드입니다//Some Controller
$myService = $this->_helper->service('MyService'); //returns an instance of the class App\Domain\Service\MyService
$result = $myService->doSomethingWithSomeData($this->getRequest()->getPost());
//etc...
-
:
//inside some method in the bootstrap
HelperBroker::addHelper(new App\Controller\Action\Helper\Service($entityManager, '\App\Domain\Service'));
을 그리고 내 컨트롤러에서이 도우미를 사용하는 방법
흠, 실제로 레지스트리와 같은 정적 클래스 인 HelperBroker를 고려하지 않은 채 글로벌 레지스트리가 없으므로 팩토리 클래스는 무엇입니까? : S 두 가지의 주요 차이점을 설명 할 수 있습니까? (공장 출동 대 서비스 찾기)? – JCM
팩토리 클래스는 전달한 매개 변수를 기반으로 무언가를 생성합니다. 팩토리에 생성 할 것을 알려주면 항상 동일한 입력에 대해 동일한 출력을 반환합니다.예를 들어 EM (ctor를 통해)과 서비스 이름/네임 스페이스 (메소드를 통해)를 주입합니다. 어쩌면이 도움이 될 것입니다 : http://stackoverflow.com/questions/1557781/whats-the-difference-between-thependency-injection-and-service-locator-patte –
@PhilippeGerber : 저는 공장을 구별하는 것이 가치가 있다고 생각합니다. 컨테이너. 전형적으로,'$ factory-> getObject ($ params)'형태의 반복적 인 호출은 요청 된 객체의 별개의 인스턴스를 생성 할 것이다. 대조적으로, 컨테이너는 보통 내부 레지스트리를 가지므로'$ container-> getObject ($ params) '형식의 모든 호출은 _same_ 인스턴스를 반환합니다. 그럼에도 불구하고 (1) 공장과 컨테이너는 모두 종속성 주입을 처리하는 배선 코드의 좋은 집이며 원래 질문의 예제는 공장으로 사용됩니다. –