디자인 모드 정보:의존 주입
18938 단어 programmingbeginnersarchitecturejava
무엇이 주입에 의존합니까?
의존 주입(Dependency injection,DI)은 소프트웨어의 구성 요소를 결합시키고 통합과 테스트를 간소화하기 위한 매우 간단한 개념이다.이것은 서브어셈블리를 만드는 것이 아니라 서브어셈블리를 요청하는 것으로 이루어집니다.
본문에서 우리는 흔히 의존항 주입과 함께 사용되는 반전 제어(inversion of control, IoC)도 언급할 것이다.이런 모델은 의존항을 주입할 때 실현을 요구하는 것이 아니라 인터페이스를 요구하는 것을 피하기 위한 것이다.
본고는 자바의 간단한 예시를 이용하여 의존 주입을 보여주지만 이 개념과 그 장점에 대해 기술과 무관한 해석을 하고자 한다.또한 대상을 대상으로 하는 디자인 모델이라도 많은 프로그래밍 언어에서 이 행동을 조정할 수 있습니다.
이 모든 것을 하나의 예로 설명합시다!
우리는 날씨를 뚜렷하게 반영할 수 있는 날씨 서비스를 제공할 것이다.현재의 실현 속에서 우리는 온도계에만 의존한다.
주입에 의존하지 않는 것부터 시작합시다.
그림에서 보듯이 Weather Service는 온도계에 의존하여 온도계를 온도 단위로 설정할 수 있다.
종속 항목 주입을 사용하지 않으면 코드가 서비스에 온도계를 만드는 새로운 인스턴스와 온도계가 사용할 Temperature Unit를 구성하게 됩니다.
public class Thermometer {
private final TemperatureUnit unit;
public Thermometer() {
this.unit = TemperatureUnit.CELSIUS;
}
}
public class WeatherService implements WeatherContract {
private final Thermometer thermometer;
// This constructor is not using dependency injection
public WeatherService() {
this.thermometer = new Thermometer();
}
}
이제 우리는 섭씨 대신 화씨도를 사용하도록 설정된 온도계를 사용하고 싶다고 상상해 보자.이를 위해, 우리는 두 단원 사이를 전환할 매개 변수를 추가했다.public Thermometer(boolean useCelsius) {
if (useCelsius) {
this.unit = TemperatureUnit.CELSIUS;
} else {
this.unit = TemperatureUnit.FAHRENHEIT;
}
}
너도 알다시피, 우리 프로그램의 사용자는 항상 그들의 장치의 실제 온도계에 접근할 수 없기 때문에, 이런 상황에서, 너는 다른 실현으로 돌아가기를 희망할 수도 있다.예를 들어, API가 당신이 있는 지역의 현재 온도를 보냅니다.서비스에서 여러 개의 실현을 통합하면 다음과 같다.
public WeatherService(boolean useRealDevice,
boolean useCelsius,
String apiKey) {
if (useRealDevice) {
this.thermometer = new Thermometer(useCelsius);
} else {
this.thermometer = new ThermometerWebService(useCelsius, apiKey);
}
}
따라서 다음과 같이 서비스를 초기화할 수 있습니다.public static void main(String[] args) {
// Not using dependency injection
WeatherContract weather = new WeatherService(true, true, null);
}
설령 그것이 매우 쉽게 사용된다 하더라도, 우리 현재 버전의 Weather Service는 진화된 것이 아니다.만약 우리가 그것의 구조를 자세히 관찰한다면, 우리는 여러 가지 설계 결함을 볼 수 있는데, 이러한 결함들은 우리를 장기적으로 괴롭힐 것이다.의존 주입이 나의 프로젝트를 개선할 수 있습니까?
제어 반전과 관련된 의존항 주입은 이 용례를 덮어쓰는 좋은 방법이다.프로그램에 사용할 온도계를 상황에 따라 선택할 수 있습니다.다음 그림에서는 새로운 아키텍처를 간략하게 설명합니다.
이 그림에서 Google의 Weather Service는 온도계 계약과 연결되어 있으며, 그 어떠한 실현도 이루어지지 않는다는 사실은 반전을 통제하는 것을 대표한다.단지 이거야.
의존 주입에 대해 Weather Service는 이제 그 구조 함수에 온도계 계약을 적용하고 이 서비스의 블록을 사용하여 이 계약을 채우는 실례를 요구한다.
public class WeatherService implements WeatherContract {
// We now use the Interface
private final ThermometerContract thermometer;
// New constructor using dependency injection
public WeatherService(ThermometerContract thermometer) {
this.thermometer = thermometer;
}
}
따라서 두 구조 함수의 WeatherService 초기화는 다음과 같습니다.public static void main(String[] args) {
// Using dependency injection
TemperatureUnit celsius = TemperatureUnit.CELSIUS;
ThermometerContract thermometer = new Thermometer(celsius);
WeatherContract weather = new WeatherService(thermometer);
}
현재, 우리의 온도계 계약은 완전히 소프트웨어의 외부 부분에 의해 설정될 수 있다.더 중요한 것은 Weather Service는 온도계 계약의 어떠한 사용 가능한 실현도 알 필요가 없기 때문에 소프트웨어 패키지를 결합할 수 있다.이것은 결코 중요하지 않은 것 같지만, 이런 간단한 책임 전환은 소프트웨어 디자인의 여러 측면에서 매우 중요하다.이것은 링크 의존항을 통해 소프트웨어 입구점에서 실례를 제어할 수 있도록 합니다.필요하기 전에 당신은 실례화를 처리할 필요가 없습니다.이런 행위는 제시된 예외 상황과 비교할 수 있는데 이러한 예외 상황은 중요한 환경에서 처리될 때까지 무시될 것이다.
의존 주입이 이게 다야?
주입에 의존하는 라이브러리를 관리할 수 있어도 항상 사용해야 하는 것은 아니라는 것을 알아야 한다.
이 라이브러리들은 왕왕 많은 상황을 덮고 있기 때문에 우선 이 모델에 익숙하지 않은 개발자들을 불쾌하게 할 수 있다.실제로 그것들은 복잡한 의존 나무의 실례화를 간소화했을 뿐 전혀 필요하지 않다.
다음 부분은 Guice를 사용하여 저희 서비스에 주입된 예입니다. 이것은 구글이 자바 개발에 의존하는 주입 프레임워크입니다.그 개념은 라이브러리에서 어떤 종류의 클래스를 자동으로 생성할 수 있도록 프로그램의 모든 구성 요소에 주입할 수 있는 연결을 인용하는 것이다.
다음 두 가지 구성 함수를 사용하여 구현할 수 있습니다.
public class WeatherService implements WeatherContract {
private final ThermometerContract thermometer;
@Inject
public WeatherService(ThermometerContract thermometer) {
this.thermometer = thermometer;
}
}
public class Thermometer implements ThermometerContract {
private final TemperatureUnit unit;
@Inject
public Thermometer(@Named(WeatherModule.TEMPERATURE_UNIT)
TemperatureUnit unit) {
this.unit = unit;
}
}
주입 모듈은 모든 필요한 인터페이스를 주어진 실현에 연결하도록 설정해야 한다.또한 enumerate Temperature Unit와 같은 특정 인터페이스 없이 객체를 주입할 수도 있어야 합니다.
이 예에서 주입은 특정 이름 "temp unit"에 바인딩됩니다.
public class WeatherModule extends AbstractModule {
public static final String TEMPERATURE_UNIT = "temp_unit";
@Override
protected void configure() {
// Named input configuration bindings
bind(TemperatureUnit.class)
.annotatedWith(Names.named(TEMPERATURE_UNIT))
.toInstance(TemperatureUnit.CELSIUS);
// Interface - Implementation bindings
bind(ThermometerContract.class).to(Thermometer.class);
bind(WeatherContract.class).to(WeatherService.class);
}
}
마지막으로, 이 모듈은 다음과 같은 방식으로 사용할 수 있으며, 여기서 위더컨트롤을 실례화할 수 있다.public static void main(String[] args) {
// Creating the injection module configured above.
Injector injector = Guice.createInjector(new WeatherModule());
// We ask for the injection of a WeatherContract,
// which will create an instance of ThermometerContract
// with the named TemperatureUnit under the hood.
WeatherContract weather = injector.getInstance(WeatherContract.class);
}
이러한 모듈은 일반적으로 주입된 원소에 좋은 맞춤형 능력을 제공하기 때문에 우리는 사용 가능한 실현에 따라 주입을 설정하는 것을 고려할 수 있다.따라서 집적 의존항 주입 시 라이브러리를 사용할 필요가 없다.그러나 이것은 대형 프로젝트에서 많은 시간과 번거로운 코드를 절약할 수 있다.
테스트 보여줘!
코드 결합의 부작용으로서 의존항 주입 모델은 모든 구성 요소의 단원이 테스트 가능한 진정한 자산을 향상시키는 것이다.이 섹션에는 Weather Service의 셀 테스트 예가 들어 있습니다.
위에서 말한 바와 같이 Weather Service는 온도계 계약을 요구하여 우리가 원하는 모든 것을 사용할 수 있도록 한다.따라서 우리는 구조 함수에서 시뮬레이션을 보내고 외부에서 그 행위를 제어할 수 있다.
public void testTemperatureStatus() {
ThermometerContract thermometer = Mockito.mock(ThermometerContract.class);
Mockito.doReturn(TemperatureUnit.CELSIUS).when(thermometer).getUnit();
WeatherContract weather = new WeatherService(thermometer);
Mockito.doReturn(-50f).when(thermometer).getTemperature();
assertEquals(
TemperatureStatus.COLD,
weather.getTemperatureStatus()
);
Mockito.doReturn(10f).when(thermometer).getTemperature();
assertEquals(
TemperatureStatus.MODERATE,
weather.getTemperatureStatus()
);
}
보시다시피 우리는 우리의 온도계를 조절할 수 있으며, 우리가 테스트하는 교실 밖에서 발버둥칠 필요가 없다.결론
의존 주입은 코드 체계 구조를 생각하는 방식으로 쉽게 스스로 실현할 수 있다.대형 프로젝트에서 장기적으로 보면 집적 의존 주입 프레임워크는 많은 시간을 절약할 수 있다.
의존 주입은 다음과 같은 여러 가지 무시할 수 없는 장점을 제공한다.
Reference
이 문제에 관하여(디자인 모드 정보:의존 주입), 우리는 이곳에서 더 많은 자료를 발견하고 링크를 클릭하여 보았다 https://dev.to/aveuiller/about-design-patterns-dependency-injection-2hah텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
우수한 개발자 콘텐츠 발견에 전념 (Collection and Share based on the CC Protocol.)