1. 의존성 주입 이란? ( DI , Dependency Injection )
- 하나의 객체에 다른 객체의 의존성을 제공하는 기술
1) 의존성 (Dependency)
- 객체 지향에서 두 클래스 간의 관계
2) 주입 ( Injection)
- 생성자나 메서드 등을 통해외부로부터 생성된 객체를 전달 받는 것.
* 의존성 주입 => 의존 관계에 있는 클래스의 객체를, 외부로 부터 생성하여 주입받는다.
부에서 객체를 관리하게 되는데 이를 IOC(inversion of Control, 제어의 역전)라 합니다. Note : IOC는 객체의 생성부터 생명주기 관리까지 컨테이너에 의해 제어 되는 것을 의미하고, 의존성 주입(DI)은 객체간의 의존성을 자기 자신이 아닌 외부에서 주입받는 개념입니다. |
2. 의존성 주입의 장 ˙ 단점
1) 장점
- 의존성 주입은 인터페이스를 기반으로 설계되며, 코드를 유연하게 한다.
- 주입하는 코드만 따로 변경하기 쉬워 리펙토링이 수월하다.
- 단위테스트를 하기가 더욱 쉬워진다.
- 클래스간 결합도를 낮춘다.
2) 단점
- 간단한 프로그램을 만들 때는 번거롭다.
- 가독성이 떨어진다.
* 짧은 개발 기간과, 더이상 유지보수를 하지 않는 프로그램을 만드는 경우는 의존성 주입을 굳이 추천하지 않으나.
일반적 상용 어플리케이션을 만들고, 지속해서 유지보수를 해야한다면, 생산성이 향상된다.
3. Dagger2 란?
- 자바와 안드로이드를 위한 의존성 주입 프레임워크
특징
- 리플렉션을 사용하지 않는다.
- 컴파일 타임에 생성된다.
Dagger2의 장점
- 자원 공유의 단순화
- 복잡한 의존성을 단순하게 설정
- 유닛 테스트를 쉽게도와준다.
- 자동 코드 생성 ( 생성된 코드는 명확하고, 디버깅이 가능)
4. Dagger2 설정
- 링크:https://github.com/google/dagger
5. Dagger2의 Annotation
1) @Module 과 @Provide
@Module은 클래스에만 붙이며 @Provide는 반드시 @Module클래스안에 선언된 메소드에만 붙입니다.
Module클래스는 의존성 주입에 필요한 객체들을 Provide메소드를 통해 관리 합니다.
Provide 메소드의 파라미터 또한 컴포넌트 구현체로부터 전달 받을 수 있습니다.
* 일반적인 사용 컨벤션
일반적으로 Module클래스는 클래스이름 뒤에 Module을 붙이고,
Provide메소드명 앞에는 provide를 붙이는 것이 일반적인 컨벤션입니다.
@Module
public class AModule {
@Provides
AA provideAA(){ //AA 오브젝트를 컴포넌트에게 제공
return new AA();
}
@Provides
BB provideBB(AA aa){ //위에서 제공하는 AA를 컴포넌트로 부터 인자로 전달받아 BB를 제공
return new BB(aa);
}
}
@Module
public class BModule {
@Provides
String provideName(){
return "Charles";
}
}
2) @Nullable
- @Provides 메서드는 null을 반환하는 것을 기본적으로 제한한다.
- null을 인젝션 하고 싶다면 @Nullable 애노테이션을 이용해야합니다.
- @Provide 메소드와 객체를 주입받을 타입이 모두 쌍으로
@Nullable 애노테이션이 붙어 있는 경우에만 null 주입을 허용하며,
그 이외의 경우에는 컴파일 타임에 에러를 발생 시킵니다.
3) @Inject
@Inject는 필드, 생성자, 메소드에 붙여 컴포넌트로부터 객체를 주입받을 수 있게 합니다.
* 실무에서는 필드 주입, 생성자 주입이 주로 사용 됩니다.
public class AA {
}
public class BB {
public BB(AA aa){
}
}
public class CC {
AA aa;
BB bb;
@Inject
public CC(AA aa, BB bb){//생성자에 주입하는 예제
this.aa = aa;
this.bb = bb;
}
}
public class Main{ //필드에 주입하는 예제
@Inject AA aa;
@Inject BB bb;
@Inject CC cc;
...
}
기본적으로 Dagger는 요청된 자료형에 맞게 Module로부터 인스턴스를 생성하여 주입을 받게 됩니다. 모든곳에서 @Inject가 동작하는것은 아닙니다. @Inject를 붙일 수 없는 경우는 다음과 같습니다.
- 인터페이스는 생성자가 없으므로 불가능
- 써드파티 라이브러리 등의 클래스는 참조가 불가능하여 애노테이션프로세싱이 안됨
- 기타 등등
4) @Component
@Component는 interface 또는 abstract 클래스에 붙일수 있습니다.
컴파일 타임에 애노테이션 프로세서에 의해 생성된 클래스는
접두어 ‘Dagger’와 @Component가 붙은 클래스이름이 합쳐진 형식의 이름을 갖습니다.
예를들면 @Component interface MyComponent{…}란 인터페이스가 있다면
DaggerMyComponent라는 클래스가 생성되게 됩니다.
@Component(modules = {AModule.class, BModule.class})
public interface MyComponent {
//provision 메소드
AA makeAA();
//member-injection 메소드
void inject(Main target);
}
Provision Method
프로비전 메소드에는 매개변수가 없고, 모듈이 제공하는 객체의 타입을 반환형으로 갖습니다. 생성된 컴포넌트 클래스에서 이 메소드를 이용하여 객체를 얻을 수 있습니다.
Member-Injection Method
의존성을 주입시킬 객체를 메소드의 파라미터로 넘기는 방법입니다. 멤버인젝션 메소드를 호출 하게 되면 타겟 클래스 내의 @Inject 필드에 객체를 주입받게 됩니다.
참고 : https://www.charlezz.com/?p=1259
참고 : 아키텍처를 알아야 앱 개발이 보인다. ( 옥수환 지음 )
'개인 공부' 카테고리의 다른 글
CI ( Continuous Integration ) (0) | 2022.03.26 |
---|---|
MVVM? (0) | 2022.03.25 |
React Native 하면서 궁금했던거. (0) | 2021.08.08 |
여러가지 기타등등.. (0) | 2021.02.15 |
Unity ? (1) | 2021.01.22 |