손으로 의존성 주입은 구성과 다형성에 대한 더 나은 대안입니까?


13

먼저, 저는 엔트리 레벨 프로그래머입니다. 사실 저는 여름 내내 최종 캡 스톤 프로젝트로 AS 학위를 마치고 있습니다. 저의 새로운 직업에서, 제가해야 할 프로젝트가 없을 때 (팀을 더 많은 신입 사원으로 채우기 위해 기다리고 있습니다), 기다리는 동안 읽고 배우는 책을 받았습니다 – 일부 교과서, 기타 코드 완성과 같은 것은 아닙니다. 이 책들을 다 읽은 후에는 인터넷을 통해 가능한 많은 것을 배우고 SOLID와 DI에 대해 배우기 시작했습니다 (우리는 Liskov의 대체 원칙에 대해 이야기했지만 SOLID 아이디어는 많지 않았습니다). 내가 배운대로, 나는 더 잘 배우기 위해 앉았고, DI를 직접 사용하는 코드를 작성하기 시작했습니다 (개발 컴퓨터에는 DI 프레임 워크가 없습니다).

내가하는 것처럼, 나는 그것이 친숙하다고 느끼는 것을 알았습니다 ... 그리고 그것은 다형성을 사용하여 추상 클래스의 구성을 사용하여 과거에했던 일과 매우 흡사합니다. 여기 더 큰 그림이 없습니까? 그것을 넘어서는 DI (적어도 손으로)에 관한 것이 있습니까? 재 컴파일하지 않고 변경하는 것까지 큰 이점이있는 일부 DI 프레임 워크의 코드가 아닌 구성의 가능성을 이해하지만 수동으로 수행 할 때 위에서 언급 한 것과 다른지 확실하지 않습니다 ... 이것에 대한 통찰력은 매우 도움이 될 것입니다!

답변:


21

DI의 기본 아이디어는 종속성을 외부에서 가져 오게하는 대신 종속성을 객체로 푸시하는 것입니다. 이것을 "제어 역전"이라고도합니다. 이를 통해 종속성을 훨씬 더 잘 제어 할 수 있으며, 단위 테스트가 쉬운 코드를 작성할 수 있습니다.

DI 프레임 워크는이 아이디어 위에 만 구축되며 배선 개체 종속성의 종종 지루한 부분을 함께 자동화합니다. 그렇지 않으면 손으로 할 때 더 큰 프로젝트에서 상당한 양의 코드가 필요할 수 있습니다.

외부 구성 파일과 별도로 종속성을 정의하기 위해 요즘 Java 및 C #과 같은 언어에서 코드 주석을 사용할 수도 있습니다. 이것들은 선언적인 스타일로 배선 의존성을 가지지 만 논리적으로 속하는 코드 자체 내에서 두 가지 장점을 모두 얻을 수 있습니다. 나에게 다시 컴파일 할 필요없이 종속성을 변경할 가능성은 실제로는 (특별한 경우는 제외하고) 거의 이루어지지 않기 때문에 가치가 없지만 코드 내에 정의 된 클래스 및 객체와의 의존성을 종종 인공적으로 분리합니다. .

제목 문제로 돌아 가기 위해 DI는 작곡이나 다형성의 대안이 아닙니다. 결국, 이 두 가지 로 가능해 졌습니다.


1
의존성 주입 (DI)은 IoC (Inversion of Control)의 한 형태입니다.
Matthew Flynn

@MatthewFlynn, 정말로. 참조를 위해 : martinfowler.com/articles/injection.html
Péter Török

1
그건 내 참고 야 그는 UI 이벤트 리스너가 IoC의 한 형태 였기 때문에 제어 반전을 수행하는 새로운 "경량 컨테이너"에 대해 이야기합니다. 그는 Spring과 다른 IoC 컨테이너가 의존성 주입 (Dependency Injection)으로하는 객체 바인딩을 더하여 다른 형태의 제어 반전과 구별합니다.
Matthew Flynn 2016 년

죄송합니다. "실제"를 놓쳤습니다. 당신이 날 모순한다고 생각했는데 ... 미안
Matthew Flynn 2016 년

마지막 단락은 기분이 좀 나아졌습니다. 나는 작은 학습 프로젝트를 수행하는 동안 계속해서 "다형성 같은 느낌이 들었습니다."라고 말했습니다. 불행히도, 내 직장의 .Net과 c #은 낡았지만 그것을 살펴보면 Unity가 내장 된 c # 프레임 워크입니까?
Drake Clarris

22

제가이 주제에 관해 읽은 최고의 기사는 James Shore 's 입니다. 나는 추상화와 다형성의 일환으로 오랫동안 " DI by Hand "를 해왔다 . 그래서 나는 전문적인 세계에 들어서고 그 용어가 계속해서 들리는 것을 듣고 난 그 단어 의미 한다고 생각하는 것과 실제로 의미하는 것 사이에 큰 차이 생겼습니다.

"종속성 주입"은 5 센트 개념의 25 달러 용어입니다.

그것은 Shore 's post의 글입니다. 예를 들면 다음과 같습니다.

주어진

class Engine {public abstract void start()}
class V8 extends Engine {...}
class V6 extends Engine {...}

글을 쓰는 대신 :

class Car
{
    private Engine engine;
    public Car()
    {
        this.engine = new V6();
    }

    public void start()
    {
        this.engine.start();
    }
}

다음과 같이 작성하십시오.

class Car
{
    private Engine engine;
    public Car(Engine a)
    {
        this.engine = a;
    }

    public void start()
    {
        this.engine.start();
    }
}

...

Car F = new Car(new V8());

따라서 Car인스턴스가 특정 Engine세부 정보 를 처리 하지 않아도됩니다 . 자동차에는 엔진 만 있으면되며 기본 엔진 기능을 구현하는 한 어떤 엔진도 신경 쓰지 않습니다. 즉, Car클래스는 특정 구현 종속성과 관련이 없습니다. 잠재적으로 런타임에 다른 곳에 "주입"됩니다.

이 특정 Car 예제에서는 "Constructor Injection"이라는 DI의 하위 유형을 사용합니다. 이는 종속성이 생성자 인수로 인계되었음을 의미합니다. setEngine(Engine a)"Setter Injection"등 의 방법을 사용할 수도 있지만 이러한 하위 유형은 나에게 도움이 될 것 같습니다.

그럼에도 불구하고, 많은 DI 프레임 워크는보다 추상적으로 참조 된 것들을 서로 연결하기위한 상용구를 제공합니다.

그게 다야.


0

지난 몇 년 동안 DI를 사용하기 시작한 전문가는 아니지만, 내가 주목 한 DI 컨테이너의 몇 가지 유용한 테마 / 기능은 (구성 / 다형성의 제품으로 생각하지 않습니다) (그러나 나는 그 문제에 시정 될 수 있습니다) :

  • 객체 생성의 중심 허브
  • 스레드 당 싱글 톤 제공
  • 가로 채기와 같은 화면 지향 기술

0

DI 외에도 루트 응용 프로그램에는 xml을 사용하여 구성하는 대신 클래스 구성 구성이 있습니다. DI 또는 IoC 프레임 워크는 필요하지 않지만, 특히 대규모 프로젝트의 경우 클래스 구성 구성을 정리할 수 있습니다. DI 프레임 워크에는 일반적으로 클래스 구성을 구성하는 데 도움이되는 자동 배선과 같은 추가 기능을 구현하는 컨테이너가 제공되기 때문입니다. 이 주제에 대한 이해를 돕기 위해 내 블로그 항목을 읽을 수 있습니다 .

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