의존성 주입 : 어떤 시점에서 새 객체를 만들 수 있습니까?


13

PHP 응용 프로그램을 리팩토링하고 있으며 가능한 많은 의존성 주입 (DI) 을 수행하려고 합니다.

나는 그것이 어떻게 작동하는지 잘 이해하고 있다고 느끼며, 수업이 훨씬 더 얇고 강건 해짐을 확실히 알 수 있습니다.

클래스 내에서 새 객체를 만드는 대신 종속성을 주입 할 수 있도록 리팩토링하고 있지만 어느 시점에서 일부 객체를 만들어야합니다. 즉, dreaded new키워드를 사용해야합니다 .

내가 지금 겪고있는 문제는 실제로 어떤 시점에서 새 객체를 만들 수 있습니까? 다른 클래스가 없어서 많은 새로운 객체를 생성하는 최상위 클래스로 끝날 것 같습니다. 이것은 잘못 느낀다.

팩토리 클래스 를 사용하여 모든 객체를 만든 블로그를 읽은 다음 팩토리를 다른 클래스에 주입합니다. 그런 다음 팩토리 메소드를 호출하면 팩토리가 새 오브젝트를 작성합니다.

이 작업에 대한 나의 관심은 이제 공장 수업이 new모두 무료 가 될 것입니다 ! 팩토리 클래스이므로 괜찮을 것 같지만 팩토리 패턴과 DI를 사용할 때 지켜야 할 규칙이 있습니까? 아니면 여기서 마크를 벗어나 있습니까?



서비스 및 정책에 IoC를 권장합니다. 모델 또는 도우미 클래스의 경우 간단히을 사용 new합니다. 물론 IoC 컨테이너를 호출해야하는 진입 점이 몇 개 있지만 많지 않아야합니다. 일반적으로 IoC를 한 번 구성한 다음 요청 당 하나의 클래스를 해결하도록 요청합니다. MVC의 경우 일반적으로 컨트롤러입니다.
코드 InChaos

언급 한 최상위 클래스는 컴포지션 루트의 일부입니다. 잘못과 거리가 멀다.
Facio Ratio

답변:


12

이것에 대해 꽤 많은 인터넷 검색을 한 후에 (위의 주석에서 언급했듯이) 내가 이야기 한 최상위 클래스는 Composition Root 라고합니다 .

실제로이 컴포지션 루트 내에 모든 객체의 생성을 추가하거나 여기에서 IoC 컨테이너를 참조하는 것이 허용되는 솔루션 인 것 같습니다.

이것에 대한 나의 원래 관심은이 최상위 클래스가 약간 엉망이 될 것이라는 것이 었습니다. 이것은 어느 정도 사실이지만, 장점은 단점이 있습니다. 예를 들어 다른 모든 클래스의 가독성, 테스트 가능성 및 유지 관리 성이 향상되었음을 알 수 있습니다.

상위 레벨 클래스는 뒤덮, 조금 지저분한 할 수 newset_property()하지만 내가 실제로 다른 클래스에 걸쳐 모두에 대해 한 곳에서 모든 코드를 가지고 선호보다는 흩어져 말을

이 방법의 성능에 대한 다른 유용한 페이지는 여기에 있습니다.


1
전에 '구성 루트'에 대해 들어 본 적이 없기 때문에 +1입니다.
c_maker

2

팩토리 클래스는 new전체에 뿌려 질 것입니다. 요청하는 객체와 해당 객체의 종속성을 생성합니다. 팩토리 작업은이 클래스에있는 올바른 객체를 인스턴스화하는 new것이 나쁘지 않습니다.

DI는 느슨하게 결합 된 디자인을 갖도록하기위한 것입니다. 각 개체에 제공되는 종속성을 변경하여 응용 프로그램을 변경할 수 있습니다. 응용 프로그램을 유연하고 확장 가능하며 쉽게 테스트 할 수 있습니다.

최상위에는 몇 개의 팩토리를 인스턴스화하고 서비스 연결을 설정하고 응답을 보내는 코드가 있습니다. new응용 프로그램에 필요한 객체를 인스턴스화하기 위해 상당한 양의 정적 호출이 있습니다. 그것은 그것이 속한 곳이 될 것입니다.


-2

여기 내 센트 :

PHP 응용 프로그램을 리팩토링하고 있으며 가능한 많은 의존성 주입을하려고합니다.

의존성 주입 프레임 워크를 사용하고 있는지 명시하지 않습니다. 당신은 분명히해야한다고 생각합니다. /programming/9348376/guice-like-dependency-injection-frameworks-in-php 필요한 기능을 제공 하십시오 .

내가 지금 겪고있는 문제는 실제로 어떤 시점에서 새 객체를 만들 수 있습니까? 다른 클래스가 없어서 많은 새로운 객체를 생성하는 최상위 클래스로 끝날 것 같습니다. 이것은 잘못 느낀다.

일반적으로 응용 프로그램을 구성하는 초기 객체의 인스턴스화를 위해 구성 또는 중심점을 사용합니다. 컨테이너가 객체를 생성합니다.

그런 다음 IoC 컨테이너를 통해 객체 (서비스, 공급자, 컨트롤러 ...)에 액세스합니다. 필요한 경우 투명하게 객체를 생성하거나 적절한 기존 인스턴스에 대한 참조를 제공합니다.

물론 특정 객체 구현 내에서 DI (데이터 구조, 사용자 정의 유형 등)가 필요하지 않은 다른 객체를 인스턴스화 할 수 있지만 이는 정상적인 프로그래밍입니다.

팩토리 클래스를 사용하여 모든 객체를 만든 블로그를 읽은 다음 팩토리를 다른 클래스에 주입합니다. 그런 다음 팩토리 메소드를 호출하면 팩토리가 새 오브젝트를 작성합니다.

일반적으로 팩토리를 통해 IoC 프레임 워크에서 일부 IoC 객체를 인스턴스화하려면 Factory를 사용합니다 (특정 객체를 인스턴스화하려면 추가 작업이 필요할 때 필요함). "new Object ()"를 사용하여 객체를 만들고 일부 속성을 설정하는 경우 팩토리 패턴을 사용하지 않아도됩니다.

다시 말해서, 클래스 또는 클래스 그룹에 팩토리 패턴을 사용하는 것은 DI를 사용하는지 여부가 아닌 (클래스 구현에 명시 적으로 팩토리가 필요하지 않은 경우가 아니라면) 클래스를 모델링하려는 방법에 따라 다릅니다.

또한 팩토리를 사용해야하는 써드 파티 라이브러리를 사용할 때 팩토리를 사용하도록 IoC 프레임 워크를 구성합니다. 이 경우, 이에 대한 통제권이 없으며 IoC 컨테이너에 다음과 같이 알려야합니다. "이 인터페이스 중 하나를 요청하면이 팩토리를 사용하여 적절한 인스턴스를 제공해야합니다."

이 작업에 대한 나의 관심은 이제 공장 수업이 새로운 무료가 될 것입니다! 팩토리 클래스이므로 괜찮을지 모르지만 팩토리 패턴과 DI를 사용할 때 지켜야 할 규칙이 있습니까? 아니면 여기서 마크를 벗어나려고합니다.

이 경우, 이러한 객체 / 서비스 / 컨트롤러 / 무엇을 위해 팩토리 패턴을 사용할 필요가 없으며, 적절한 클래스를 "신규"로 인스턴스화하고 다른 모든 것을 주입하도록 IoC를 구성 할 수 있습니다.

도움이 되길 바랍니다.


답변 주셔서 감사하지만, IoC 컨테이너는 내가 언급 한 '최상위 클래스'입니다. 거기에 객체 만 만들 수 있다면 올바른 엉망이 될 것입니다.
Gaz_Edge

4
doing DI manually beats the whole purpose of using an Inversion of Control container- "구성 파일에서 종속성을 중앙 집중화하고있다" 는 말이 맞다면 IoC 컨테이너가 실제로하기 때문입니다. DI의 실제 목표는 디커플링이며, 생성자 메소드에서 종속성을 제공하여이를 수행 할 수 있습니다. 이를 위해 DI 프레임 워크가 전혀 필요하지 않습니다.
Robert Harvey

객체를 생성하지 않거나 필요한 곳에서 IoC 컨테이너를 요청하거나 필드 / 인수 삽입을 사용하여 클래스에 IoC 컨테이너가 항상 생성하는 적절한 클래스를 자동으로 주입합니다.
jjmontes

1
매우 큰 응용 프로그램을 위한 프레임 워크가 필요하다는 데 동의합니다 . 많은 응용 프로그램이 그다지 크지 않으며 DI 프레임 워크 사용의 추가 복잡성으로 인한 이점이 없습니다.
Robert Harvey

2
나는 그런 말을하지 않았다. 단순히 DI 컨테이너가 필요하지 않다고 말했습니다.
Robert Harvey
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.