최근 Service Locator 안티 패턴에 관한 Mark Seemann의 기사를 읽었습니다 .
필자는 ServiceLocator가 안티 패턴 인 두 가지 주요 이유를 지적합니다.
API 사용법 문제 (완전히 괜찮습니다)
클래스가 서비스 로케이터를 사용할 때 대부분의 경우 클래스에 PARAMETERLESS 생성자가 하나만 있으므로 종속성을 확인하기가 매우 어렵습니다. ServiceLocator와 달리 DI 방식은 생성자의 매개 변수를 통해 종속성을 명시 적으로 노출하므로 IntelliSense에서 종속성을 쉽게 확인할 수 있습니다.유지 보수 문제 (나를 당혹스럽게한다)
다음 expample을 고려하십시오
서비스 로케이터 접근 방식을 사용하는 'MyType' 클래스가 있습니다 .
public class MyType
{
public void MyMethod()
{
var dep1 = Locator.Resolve<IDep1>();
dep1.DoSomething();
}
}
이제 'MyType'클래스에 다른 종속성을 추가하려고합니다
public class MyType
{
public void MyMethod()
{
var dep1 = Locator.Resolve<IDep1>();
dep1.DoSomething();
// new dependency
var dep2 = Locator.Resolve<IDep2>();
dep2.DoSomething();
}
}
그리고 여기 내 오해가 시작됩니다. 저자는 말합니다 :
주요 변경 사항을 도입했는지 여부를 판단하기가 훨씬 어려워집니다. Service Locator가 사용되는 전체 애플리케이션을 이해해야하며 컴파일러가 도움을주지 않습니다.
그러나 DI 접근 방식을 사용하는 경우 잠시 기다립니다. 생성자 주입의 경우 생성자에 다른 매개 변수와의 종속성이 도입됩니다. 그리고 문제는 여전히있을 것입니다. ServiceLocator 설정을 잊어 버린 경우 IoC 컨테이너에 새 매핑을 추가하는 것을 잊어 버릴 수 있으며 DI 접근 방식에 동일한 런타임 문제가 발생합니다.
또한 저자는 단위 테스트 어려움에 대해 언급했습니다. 그러나 DI 접근법에 문제가 없을까요? 해당 클래스를 인스턴스화 한 모든 테스트를 업데이트해야합니까? 테스트를 컴파일 할 수 있도록 새로운 조롱 된 종속성을 전달하도록 업데이트합니다. 그리고 그 업데이트와 시간 소비로 인한 이점은 없습니다.
Service Locator 접근 방식을 방어하려고하지 않습니다. 그러나이 오해로 인해 나는 매우 중요한 것을 잃어 가고 있다고 생각합니다. 누군가 내 의심을 풀 수 있습니까?
업데이트 (요약) :
내 질문에 대한 대답은 "서비스 로케이터가 안티 패턴입니까?"는 실제로 상황에 따라 다릅니다. 그리고 나는 당신의 도구 목록에서 그것을 무시하지 않는 것이 좋습니다. 레거시 코드를 다루기 시작할 때 매우 유용 할 수 있습니다. 운 좋게도 프로젝트를 시작할 때 운이 좋으면 서비스 로케이터에 비해 몇 가지 장점이있는 DI 접근 방식이 더 나은 선택 일 수 있습니다.
그리고 새 프로젝트에 Service Locator를 사용하지 않을 것을 확신시킨 주요 차이점은 다음과 같습니다.
- 가장 분명하고 중요한 : Service Locator는 클래스 종속성을 숨 깁니다.
- 일부 IoC 컨테이너를 사용하는 경우 시작시 모든 생성자를 스캔하여 모든 종속성을 확인하고 누락 된 매핑 (또는 잘못된 구성)에 대한 즉각적인 피드백을 제공합니다. IoC 컨테이너를 서비스 로케이터로 사용하는 경우 불가능합니다
자세한 내용은 아래에 나와있는 훌륭한 답변을 읽으십시오.