하나의 구현을 구성하는 수많은 사람들. DI 희망이 없습니까? 서비스 로케이터를 사용 하시겠습니까?


14

주사를 받아들이지 않고 직접 의존성을 구성하는 1001 명의 고객이 있다고 가정 해보십시오. 보스에 따르면 1001을 리팩토링하는 것은 옵션이 아닙니다. 실제로는 소스 파일뿐만 아니라 클래스 파일에도 액세스 할 수 없습니다.

우리가해야 할 일은이 1001 클라이언트가 통과하는 시스템을 "현대화"하는 것입니다. 우리가 좋아하는 모든 것을 리팩터링 할 수 있습니다. 종속성은 해당 시스템의 일부입니다. 그리고 이러한 의존성 중 일부는 새로운 구현으로 변경되어야합니다.

우리가하고 싶은 것은이 다수의 클라이언트를 만족시키기 위해 다양한 의존성 구현을 구성 할 수있는 능력이 있다는 것입니다. 안타깝게도 DI는 클라이언트가 생성자 또는 설정자를 사용한 주입을 허용하지 않기 때문에 옵션으로 보이지 않습니다.

옵션 :

1) 클라이언트가 현재 필요한 것을 수행 할 수 있도록 클라이언트가 사용하는 서비스 구현을 리팩터링하십시오. 뱅 우린 끝났어 융통성이 없습니다. 복잡하지 않습니다.

2) 구현을 리팩토링하여 작업을 팩토리를 통해 얻은 또 다른 종속성에 위임하십시오. 이제 팩토리를 리팩토링하여 모든 구현을 제어 할 수 있습니다.

3) 구현을 리팩터링하여 서비스 로케이터를 통해 얻은 또 다른 종속성에 작업을 위임하십시오. 이제 hashmap약간의 캐스팅이 진행되는 객체에 대한 문자열 일 수있는 서비스 로케이터를 구성하여 모두가 사용하는 구현을 제어 할 수 있습니다 .

4) 아직 생각조차 못했던 것.

목표:

무의미한 복잡성을 추가하지 않고 이전에 잘못 설계 한 기존 클라이언트 코드를 미래로 드래그하여 발생하는 설계 손상을 최소화합니다.

고객은 의존성 구현을 알거나 제어해서는 안되지만로 구현해야한다고 주장합니다 new. 우리는 통제 할 수 없지만 new그들이 만들고있는 수업은 통제합니다.

내 질문:

내가 무엇을 고려하지 못했습니다?


Doc Brown의 질문

다른 구현간에 구성 할 가능성이 정말로 필요합니까? 무슨 목적을 위해?

민첩. 미지의 많은. 경영진은 변화의 잠재력을 원합니다. 외부 세계에 대한 의존성 만 잃습니다. 또한 테스트.

다른 구현 간을 전환하려면 런타임 역학이 필요하거나 컴파일 타임 역학이 필요합니까? 왜?

컴파일 타임 메카닉이면 충분합니다. 테스트 제외.

구현간에 전환해야하는 세분성 한 번에? 모듈 당 (각 클래스 그룹을 포함)? 수업 당?

1001 중에서 한 번에 하나만 시스템을 통해 실행됩니다. 모든 클라이언트가 한 번에 사용하는 것을 변경하는 것이 좋습니다. 의존성을 개별적으로 제어하는 ​​것이 중요 할 수 있습니다.

누가 스위치를 제어해야합니까? 귀하 / 개발자 팀만? 관리자? 각 고객은 스스로? 아니면 클라이언트 코드의 유지 관리 개발자? 그렇다면 정비공은 얼마나 쉽고 견고하며 완전해야합니까?

테스트를위한 개발 외부 하드웨어 종속성으로서의 관리자가 변경됩니다. 테스트 및 구성이 쉬워야합니다.


우리의 목표는 시스템을 빠르고 현대화 할 수 있음을 보여주는 것입니다.


구현 스위치의 실제 사용 사례?

하나는, 하드웨어 솔루션이 준비 될 때까지 일부 데이터는 소프트웨어에 의해 제공 될 것입니다.


1
나는 공장이나 로케이터를 세계적인 상태로 저장함으로써 많은 것을 성취 할 것이라고 생각하지 않습니다. 왜 귀찮게? 종속성을 대체하는 클라이언트를 테스트 하시겠습니까?
Basilevs

사용자 정의 클래스 로더 사용을 고려하십시오.
Basilevs

호기심에서이 시스템은 무엇을 하는가?
Prime

답변:


7

글쎄, 지원되는 솔루션의 기술적 세부 사항과 정확한 차이점을 완전히 이해하지는 못하지만 IMHO는 먼저 실제로 필요한 유연성을 찾아야합니다.

스스로에게 물어봐야 할 질문은 다음과 같습니다.

  • 다른 구현간에 구성 할 가능성이 정말로 필요합니까? 무슨 목적을 위해?

  • 다른 구현 간을 전환하려면 런타임 역학이 필요하거나 컴파일 타임 역학이 필요합니까? 왜?

  • 구현간에 전환해야하는 세분성 한 번에? 모듈 당 (각 클래스 그룹을 포함)? 수업 당?

  • 누가 스위치를 제어해야합니까? 귀하 / 개발자 팀만? 관리자? 각 고객은 스스로? 아니면 클라이언트 코드의 유지 관리 개발자? 그렇다면 정비공은 얼마나 쉽고 견고하며 완전해야합니까?

이러한 질문에 대한 답을 염두에두고 생각할 수있는 가장 간단한 솔루션을 선택하여 필요한 유연성을 제공하십시오. 추가 노력이 필요한 경우 "경우에 따라"확실하지 않은 유연성을 구현하지 마십시오.

답변에 대한 답변으로 : 실제 사용 사례가 하나 이상있는 경우이를 사용하여 설계 결정을 확인하십시오. 해당 사용 사례를 사용하여 어떤 솔루션이 가장 적합한 지 알아보십시오. "공장"또는 "서비스 로케이터"가 필요한 것을 제공하는지 또는 다른 것이 필요한지 확인하십시오. 두 솔루션이 모두 귀하의 경우에 똑같이 좋다고 생각하면 주사위를 던집니다.


좋은 질문입니다! 업데이트를 참조하십시오.
candied_orange

실제 사용 사례로 업데이트되었습니다.
candied_orange

@CandiedOrange : 나는 당신에게 약간의 물고기를 줄 수 없습니다, 나는 당신이 혼자 낚시하는 것을 도울 수 있습니다 :-)
Doc Brown

이해했다. 나는 더 나은 미끼 또는 다른 낚시 구멍이 필요한지 궁금해하는 물을 쳐다보고 있습니다. 나는 적절한 DI를하고 싶지만이 상황은 그것을 허용하지 않는 것 같습니다.
candied_orange

1
@CandiedOrange DI가 다른 무엇보다 "좋거나"더 좋기 때문에 DI를하고 싶은 욕구에 매달리지 마십시오. DI는 문제에 대한 하나의 특별한 해결책입니다. 그러나 항상 가장 "적합한"솔루션은 아닙니다. 그것을 사랑하지 마라 ... 그것을 그대로 취급하십시오. 도구입니다.
svidgen

2

내가 올바르게하고 있는지 확인하십시오. 당신은 일부 클래스, C1,...,Cn즉 직접 호출하는 많은 클라이언트 로 구성된 서비스 가 있습니다 new Ci(...). 그래서 나는 D1,...,Dn훌륭하고 현대적인 새로운 클래스로 새로운 내부 서비스를 만들고 의존성을 주입하고 (스택을 통해 그러한 의존성을 허용하는) Ci인스턴스화하고 아무것도하지 않기 위해 다시 작성하는 솔루션의 일반적인 구조에 동의한다고 생각합니다. 로 위임하십시오 Di. 문제는 그것을하고 당신이 몇 가지 방법을 제안하는 방법이다 2하고 3.

와 유사한 제안을 2합니다. Di내부 및 내부적으로 종속성 주입을 R사용한 다음 객체 그래프를 구성하는 일반적인 컴포지션 루트 (적절한 경우 프레임 워크 사용) 를 만들 수 있습니다 . 밀어 R정적 공장 뒤에 각이하게 Ci그것의 얻을 Di것을 통해. 예를 들어

public class OldClassI {
    private final NewClassI newImplementation;

    public OldClassI(Object parameter) {
        this.newImplementation = CompositionRoot.getInstance().getNewClassI(parameter);
    }
}

본질적으로 이것은 솔루션 2이지만 나머지 팩토리 주입과 함께 모든 팩토리를 한 위치에 수집합니다.


동의합니다. 이것이 옵션 3의 서비스 로케이터와 어떻게 다른지 확실하지 않습니다. 호출 할 때마다 새 인스턴스를 빌드 할 예정 getInstance()입니까?
candied_orange

@CandiedOrange 이것은 아마도 사용법의 충돌 일 것입니다. 서비스 로케이터는 본질적으로 유형에서 객체로의 해시 맵 일뿐입니다.이 구성 루트는 다른 객체를 구성하는 많은 메소드가있는 객체입니다.
walpen

1

단순하면서도 멋진 단일 구현으로 시작하십시오.

나중에 추가 구현을 작성해야하는 경우 구현 결정이 언제 발생하는지에 대한 문제입니다.

"설치 시간"유연성이 필요한 경우 (각 클라이언트 설치는 단일 정적 구현을 ​​사용) 여전히 멋진 작업을 수행 할 필요는 없습니다. 다른 DLL 또는 SO (또는 lib 형식이 무엇이든)를 제공하십시오. 클라이언트는 lib폴더에 올바른 것을 넣으면됩니다 ...

런타임 유연성이 필요한 경우 씬 어댑터와 구현 선택기 메커니즘 만 있으면됩니다. 팩토리, 로케이터 또는 IoC 컨테이너 중 어느 것을 사용하든 대부분은 약합니다. 유일한 중요한 어댑터와 로케이터 사이의 차이는 반환 된 객체는 싱글 또는 전용 인스턴스 여부) 명명 및 b)이다. 그리고 팩토리 / 로케이터 인 IoC 컨테이너의 가장 큰 차이점은 누가 누구에게 전화하는지 입니다. (종종 개인적인 취향의 문제)

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.