DI / IoC를 사용하면“새”키워드가 모두 사라 집니까?


21

Dependency Injection과 Inversion of Control 컨테이너 를 사용하면 코드에서 " "키워드가 모두 제거 new됩니까?

다시 말해서, 모든 객체 / 종속성은 아무리 단순하거나 수명이 짧더라도 IoC 컨테이너 내에서 "등록"되어이를 사용해야하는 메소드 / 클래스에 주입되어야합니까?

그렇지 않다면, 의존성 / 개체가 IoC 컨테이너에 등록되는 것과 비교하여 new키워드 를 통해 구체적인 참조로 "인라인"으로 생성되는 것 사이의 선을 어디에 그리 십니까?


나는 "새로운 단어가 4 글자 단어입니까?"라는 문구를 따라 같은 생각을했습니다.
Michael Easter

답변:


27

교리를 피하십시오. 옳은 일을하십시오.

나는 동작이없는 데이터 구조에 "new"를 사용하는 것을 선호합니다.

클래스에 동작이 있으면 해당 동작의 범위를 봅니다. 무국적 상태이고 의존성이없는 경우, 나는 "새로운"쪽으로 몸을 기울입니다. 상태 저장 리소스 (예 : 데이터베이스 또는 파일) 또는 해당 리소스가있는 다른 클래스에 대한 종속성을 추가해야하는 경우에만 DI로 리팩토링을 시작합니다.


15
"독점 피하기"에 +1 무슨 일이 일어나고 있는지 또는 어디에서 올바르게 사용해야하는지 이해하지 않고 동작을 따라가는 함정에 빠지기에는 너무 쉬운 방법입니다.
Wayne Molina

@Alex 나는 이것을 좋아한다. 매우 실용적인 접근 방식. 재미있게도, 나는 내 질문 new에 자극을주는 내 자신의 코드에 'ed 의존성을 보여주는 내 질문에 약간의 코드를 추가 하려고했다. 기능이나 "행동"자체가없고 단순한 속성 만있는 간단한 클래스였습니다.
CraigTP

11

에서 내 책 , 나는 안정과 구분 제공 휘발성 종속성 . 휘발성 의존성과 함께 DI를 사용하는 것이 가장 중요하지만, 종종 안정적인 의존성을 추상화하고 주입하여 더 느슨한 결합을 달성 할 수 있습니다.

DI의 적용이 DI 컨테이너에 의존해서는 안된다는 것을 명심하십시오 . 경우에 가난한 사람의 DI를 사용하고, 어떤 new키워드가 제거되지 않습니다 - 그들은 단지로 이동 구성 루트 .

어떤 사람들은 실제로 DI 컨테이너보다 가난한 사람의 DI를 선호합니다. 유지 관리 비용은 더 높을 수 있지만 대신 컴파일 타임 안전을 얻습니다. 나는 최근 들어으로 댄 북한 말 : " new새로운이다 new":)

이것이 의미하는 것은 DI 컨테이너를 사용하여 컴포지션 루트를 구현하는 대신 단순히 중첩 된 new명령문을 포함하는 것 입니다.


Mark, 내 트위터 의견을 조금 확장하기 위해 프로그래머는 구현시 특정 오류를 다루지 않는 개념적 화이트 보드 질문에 적합한 장소입니다.
Adam Lear

3
스택 오버플로는 의존성 주입 태그에 2000 개 이상의 질문이 있으며 많은 질문 이 이와 같습니다. 프로그래머는 같은 태그에 23 개의 질문이 있습니다. 이러한 수치를 바탕으로 개발자는 이와 같은 질문에 대한 답변을 얻을 수있는 가장 큰 기회를 어디로 가져 가야합니까?
Mark Seemann

1
많은 질문들이 프로그래머들에게 우선합니다. 이 사이트는 SO에 대한 개념적 질문을하고 전용 주택을 제공하기 위해 만들어졌습니다. 그리고 우리는 여전히 성장하고 있습니다. 현재 진행중인 작업이지만 특정 구현 문제와 관련이없는 이상적 질문은 여기서 마이그레이션됩니다. 그 동안 할 수있는 일을합니다.
Adam Lear

3

"new"는 금지 된 키워드가 아닙니다. 내 개인 규칙 :

모든 "서비스"(저는 하나에 만 관련된 하나 이상의 메소드를 제공하도록 설계된 클래스를 서비스라고 부릅니다 (예 : 데이터베이스 액세스, 지정된 도메인과 관련된 데이터 검색 / 업데이트)는 IOC 컨테이너에 등록됩니다. 어떤 클래스가 사용해야하는 특정 서비스의 구현을 얻는 방법에 대한 결정을 내릴 필요는 없습니다. 따라서 기존 서비스를 사용해야 할 때마다 클래스와 IOC 컨테이너를 제공하도록 구성해야합니다. 구현이 어떻게 작동하는지 모르고 웹 서비스가 될 수도 있고 신경 쓰지 않을 것이라고 상상해보십시오.

모든 bean 또는 모델은 "new"키워드 또는 IOC 등록 팩토리를 사용하여 작성해야합니다 (기본 특성을 사용하도록 설정해야 할 경우). 정적 메소드 만 포함하는 특정 유틸리티 클래스 (예 : 수학 유틸리티 서비스)도 있습니다. 이들이 완전히 독립형이고 데이터베이스 연결이나 다른 IOC 등록 서비스가 필요하지 않은 경우 IOC에서 제외하고 정적으로 호출해야합니다. 그러나 그러한 클래스 중 하나가 기존 IOC 등록 서비스를 사용해야하는 경우 단일 클래스로 변경 하여 IOC에 등록합니다.


2

나는 이전에 제기 된 기존 답변에 추가하고 싶고 new순수한 가치 객체 인 객체 (즉 속성 / getter / setter 만 있음)를 만드는 것이 좋습니다. 자세한 내용은 Google 테스팅 블로그 를 참조하십시오 .


링크의 경우 +1 이 블로그 게시물에서 포인트 9 질문에 응답하고이 아니어야한다 무엇을 사이에 실제적인 구분을 제공하는 new'에드
CraigTP

1

사용하는 언어에 따라 다릅니다. 만약 당신의 언어가 당신이 객체를 사용하여 실제 객체와 레코드 (값 객체, 구조체) 모두를 나타내도록 강요한다면, 대답은 아마도 아니오 일 것입니다.

"실제"객체에 대해 말하면 인스턴스를 명시 적으로 생성하는 데 아무런 문제가 없습니다. 그러나 모든 클래스는 단일 책임 원칙을 따라야합니다. 의존하는 서비스의 구현자를 선택하는 것은 클래스의 책임이되어서는 안됩니다. 그러나 특정 서비스의 구현 자에게 제공해야 할 책임이있는 수업이 있습니다. IoC는 그러한 클래스 일 수 있습니다. 실제로 모든 유형의 공장은 그러한 클래스입니다.

요약하자면, 그러한 클래스 만 객체를 직접 인스턴스화해야하며, 인스턴스화 할 클래스를 선택해야하는 책임은 누구에게 있습니다.
다음 기준이 도움이 될 수 있습니다. http://en.wikipedia.org/wiki/GRASP_(object-oriented_design)#Creator


1

한마디 : 아니다.

더 많은 단어 : 의존성 주입은 정확히입니다. 다른 개체가 의존하는 리소스를 소개하지만 다른 소스에서 복잡한 세부 정보를 알 수없는 방법입니다. DI를 사용한다고해서 프로그램에서 NOTHING이 다른 객체를 만드는 방법을 알아야한다는 것은 아닙니다. 사실, 나는 사소하지 않은 프로그램이 "새로운"키워드 (또는 리플렉션 기반 대안)를 완전히 피하는 것은 불가능하다고 주장한다. 그러나 DI는이 개체를 다른 개체와 밀접하게 연결하는 많은 종속성을 필요로하는 복잡한 개체를 만드는 방법을 알 필요가없는 개체는 이러한 밀접한 커플 링 지식을 모두 가지고 있지 않아야한다는 것을 의미합니다.

저는 O / O 소프트웨어 디자인의 두 가지 주요 이론 인 GRASP와 SOLID를 연구 할 것입니다. GRASP는 객체의 목적을 연구하고 "이 객체가 다른 유형의 새 객체를 생성해야합니까?이 객체의"작업 설명 "부분입니까?"라고 스스로에게 묻습니다. SOLID는 한 걸음 더 나아갑니다. "S"는 "단일 책임 원칙"을 나타내며, 이는 개체에 하나의 작업이 있어야하며 프로그램에서 해당 특정 작업을 수행하는 유일한 개체 여야한다는 것을 명확하게 나타냅니다.

따라서 GRASP는 일반적으로 이러한 새 객체를 생성하는 기존 클래스를 살펴보고 원하는 수준의 "응집력"을 유지하면서이 객체를 생성하는 작업이 이미 수행 한 작업에 적합한 클래스를 찾는 것이 좋습니다. SOLID는 응집력이 핵심임을 알려줍니다. 이러한 객체를 만드는 작업은 클래스에 주입해야하는 일부 팩토리에 제공되어야합니다. 프로그램의 복잡성이 계속 증가함에 따라 리팩토링하려는 의지와 함께 이러한 방법 중 하나를 준수하면 매우 유사한 아키텍처가 생성 될 것입니다.

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