정상에서 IT를 외치다

[Dagger] Dagger step3 - Subcomponent와 scope 본문

안드로이드

[Dagger] Dagger step3 - Subcomponent와 scope

Black-Jin 2019. 9. 16. 01:35
반응형

안녕하세요. 블랙진입니다.


지난 포스팅에서 정의한 카페 정보를 가져오는 예제를 활용하여 SubComponent, Scope 사용법에 대해 살펴보겠습니다.


SubComponent 특징


1. 그래프를 분할하여 캡슐화 합니다.

2. 상위 컴포넌트를 상속하므로 하위 컴포넌트는 상위 컴포넌트의 객체에 의존할 수 있습니다.

3. 하위 컴포넌트는 상위 컴포넌트와 생명주기를 다르게 가져갈 수 있습니다.

4. 하위 컴포넌트는 또 다른 하위 컴포넌트를 가질 수 있습니다.


(SubComponent 설명은 찰스의 블로그 내용을 그대로 가져왔습니다.)




객체 그래프



앞선 예제에서는 CoffeeMaker를 계속 새로 생성하였습니다. 여기서 CoffeeMaker와 Heater는 한 쌍으로 존재합니다. 이번 예제에서 이 둘을 같은 Compoent와 Scope로 생성 될 수 있도록 수정해 보겠습니다.



Component 변경


1. scope 생성


Scope는 어노테이션을 사용해 생성할 수 있습니다.

@Scope
@Retention(RetentionPolicy.RUNTIME) //컴파일 이후에도 JVM에 의해서 참조가 가능합니다.
//@Retention(RetentionPolicy.CLASS) //컴파일러가 클래스를 참조할 때까지 유효합니다.
//@Retention(RetentionPolicy.SOURCE) //어노테이션 정보는 컴파일 이후 없어집니다.
public @interface CoffeeScope {
}


2. Component 수정


Subcomponent인 CoffeeComponent를 생성해 줍니다. Subcomponent는 빌더 패턴들 사용해 구현해 주셔야 합니다.

@CoffeeScope
@Subcomponent(modules = {CoffeeModule.class})
public interface CoffeeComponent {

CoffeeMaker coffeeMaker();

@Subcomponent.Builder
interface Builder {
CoffeeComponent build();
}
}


CafeComponent에서는 Builder를 사용해 Subcomponent를 선언해 줍니다.

@Singleton
@Component(modules = CafeModule.class)
public interface CafeComponent {

CafeInfo cafeInfo();

CoffeeBean coffeeBean();

CoffeeComponent.Builder coffeeComponent();
}


3. Module 수정


CoffeeModule에서는 CoffeeMaker와 Heater를 제공해 줍니다. 이때 이 둘의 Scope를 동일하게 생성해 줍니다.

@Module
public class CoffeeModule {

@CoffeeScope
@Provides
CoffeeMaker provideCoffeeMaker(Heater heater) {
return new CoffeeMaker(heater);
}

@CoffeeScope
@Provides
Heater provideHeater() {
return new Heater();
}

}


CafeModule에서는 CafeInfo와 CoffeeBean을 제공해 줍니다.

@Module
public class CafeModule {

@Singleton
@Provides
CafeInfo provideCafeInfo() {
return new CafeInfo("BlackJin");
}

@Provides
CoffeeBean provideCoffeeBean() {
return new CoffeeBean();
}
}


4. 사용예제

//카페를 생성합니다.
CafeComponent cafe = DaggerCafeComponent.create();

//생성한 카페 정보를 가져옵니다.
CafeInfo cafeInfo1 = cafe.cafeInfo();
CafeInfo cafeInfo2 = cafe.cafeInfo();

cafeInfo1.welcome();
cafeInfo2.welcome();
System.out.println();

//@SingleTon 이기 때문에 두 객체는 값은 값을 반환합니다.
System.out.println("cafeInfo1 : " + cafeInfo1.hashCode() + " , cafeInfo2 : " + cafeInfo2.hashCode());

//카페에서 커피 구성을 생성합니다.
CoffeeComponent coffeeComponent1 = cafe.coffeeComponent().build();
CoffeeComponent coffeeComponent2 = cafe.coffeeComponent().build();

//커피 구성은 생성 할 때마다 다른 객체를 반환해야 합니다.
System.out.println("coffee1 : " + coffeeComponent1.hashCode() + " , coffee2 : " + coffeeComponent2.hashCode());

//커피 구성에 커피 메이커는 동일합니다.
CoffeeMaker coffeeMaker1 = coffeeComponent1.coffeeMaker();
CoffeeMaker coffeeMaker2 = coffeeComponent1.coffeeMaker();
System.out.println("coffeeMaker1 : " + coffeeMaker1.hashCode() + " , coffeeMaker2 : " + coffeeMaker2.hashCode());

//커피기기와 히터는 동일합니다.
//커피 콩은 카페에서 매번 생성하므로 다릅니다.
System.out.println();

CoffeeBean coffeeBean1 = cafe.coffeeBean();
coffeeMaker1.brew(coffeeBean1);

System.out.println();

CoffeeBean coffeeBean2 = cafe.coffeeBean();
coffeeMaker2.brew(coffeeBean2);


에제에서 사용한 코드는 깃허브에서 보실 수 있습니다.

반응형
Comments