2012-02-27 4 views
1

Dependency Injection을 사용하면 객체 지향 코드를 작성하는 방식이 바뀌고 있습니다. 예를 들어, 아래 나는 것 DI 내 코드 구조를 사용하여 DI의존성 주입은 OOP에 반대합니까?

없이
Interface: DataAdapter 
SqliteDataAdapter implements DataAdapter 
XMLDataAdapter implements DataAdapter 
OracleDataAdapter implements DataAdapter 

// Initialization 
DataAdapter adapter = new SqliteDataAdapter(); 
DataAdapter adapter = new XMLDataAdapter(); 
DataAdapter adapter = new OracleDataAdapter(); 

만 할 것이 무엇인가 :

이 변경에 대한 이유는
Interface: DataAdapter 
SqliteDataAdapter implements ISqliteDataAdapter, DataAdapter 
XMLDataAdapter implements IXMLDataAdapter, DataAdapter 
OracleDataAdapter implements IOracleDataAdapter, DataAdapter 

// Initialization 
ISqliteDataAdapter adapter = new SqliteDataAdapter(); 
IXMLDataAdapter adapter = new XMLDataAdapter(); 
IOracleDataAdapter adapter = new OracleDataAdapter(); 

입니다 내 모듈의 I 수 바인드 한 인터페이스 ~ 1 등급. 이것은 나쁜 습관입니까? 그렇다면 올바른 해결책은 무엇입니까?

DI가 인터페이스 사용의 전체 목적을 변경하지 않습니까?

편집 : 제안으로 내가 어떻게 여러 어댑터를 사용할 수있을 것 않으면 나의 DI 컨테이너

bind(ISqliteDataAdapter.class).to(SqliteDataAdapter.class); 
bind(IXMLDataAdapter.class).to(XMLDataAdapter.class); 
bind(IOracleDataAdapter.class).to(OracleDataAdapter.class); 

에 대한 구속력을 다음? 내 응용 프로그램에서 XMLDataAdapter와 SQLDataAdapter를 모두 사용해야하는 경우에는 어떻게해야합니까?

bind(DataAdapter.class).to(SqliteDataAdapter.class); 

편집 : 여기

인스턴스를 얻을 수있는 현재의 호출입니다 :

@inject protected DataAdapter dataAdapter; 
// In this case I don't have a choice on which type of data adapter It's going to create 
// It's already defined in my module file and it's pointing to one of the 3 DataAdapters 
:

여기
@inject protected ISqliteDataAdapter dataAdapter; 

내가 단지 1 인터페이스를 갖는 그것을 할 방법입니다

제가 이해하려고하는 것은 어떻게 대구를 구조화 할 수 있습니까? 내가 DataAdapter의 모든 유형에 대한 인터페이스를 갖지 않고 주입하는 객체의 유형을 제어 할 수있는 방식으로.

+0

[IoC를 사용할 때 인터페이스 추상화에 대해 혼란 스러울 수 있습니다.] (http://stackoverflow.com/questions/5144622/im-confused-about-interface-abstractions-when-using-ioc) –

+0

그 스레드를 이미 읽고, 내 질문에 대답하지 않습니다. – aryaxt

+3

왜 안 되니? 1 : 1 인터페이스가 가장 좋은 방향이 아니라는 것은 꽤 분명합니다. 따라서 DI는 인터페이스 사용의 전체 목적을 변경하지 않습니다. 두 번째 예제에서와 같이 코드를 구조화하려는 이유가 무엇입니까? 각각의'adapter' 변수를'DataAdapter'로 선언 할 수없는 이유는 무엇입니까? 세 가지 새로운 인터페이스가 추가로 얻게 된 가치는 무엇입니까? –

답변

5

this를 참조하십시오. 우리가 인터페이스를 가지고있는 이유는 특정 클래스에 의존하지 않는 코드를 작성할 수 있기 때문에, 변경없이 많은 클래스가있는 작업을 할 수 있기 때문입니다. 우리가 필요로하는 수업이 하나 밖에 없기를 기대한다고해도, 앞으로는 바뀔 수도 있습니다. 인터페이스 프로그래밍을 통해 상상조차 할 수없는 변화를 설명 할 수도 있습니다.

DI는 코드의 테스트 가능성과 적응성을 극대화하기 위해 위의 개념을 특유의 방식으로 사용합니다. 그래서 저는 DI가 이고 실제로는입니다.

즉, 나는 이런 종류의 시스템에 관련된 사람에게 발행해야한다는 경고가 하나 있다고 생각합니다.SqliteDataAdaptor과 같은 본격적인 수업을 작성한 다음 "인터페이스 추출"버튼을 눌러 ISqliteDataAdaptor 인터페이스를 제공 할 위험이 있습니다. 이 연습은 매우입니다. 특히 많이 발생하는 경우 특히 그렇습니다. 대신, 보통 ISqliteDataAdaptor을 먼저 설계해야하며, 그런 다음 현명한 구현을 작성할 수 있습니다.

1

종속성 주입은 인스턴스화 된 것을 제어하고 해당 논리를 단일 위치에 배치하는 것에 관한 것입니다. 작성한 코드는 사용하는 기본 유형 (인터페이스)을 변경하면 안됩니다.

두 경우 모두 사용하는 개체 유형으로 DataAdapter가 있어야합니다. 당신은 종속성 주입 컨테이너 이 아닌 인스턴스 유형을 결정합니다. 컨테이너입니다.

또한 내가 DI가 인터페이스를 갖는 자연적인 결과임을 말할 것

+0

을 기반으로 인스턴스를 가져 오십시오.하지만 인터페이스를 1 클래스에 바인딩 할 수 있다고 언급 했으므로이 경우 솔루션은 무엇입니까? – aryaxt

+0

하지만 종속성 주입 컨테이너에서 인스턴스를 가져온 경우 DataAdapter 유형을 사용할 수없는 이유는 무엇입니까? –

+0

@ LiiviuT. 그의 시스템에서와 같이 모든 구성 요소는 잠재적으로 주사 할 수 있도록 설계되었습니다. 따라서 질문은 "프로그래밍 인터페이스", 특히 DI에 대한 엄격한 준수에서 비롯된 것 같습니다. –