6. DI (Dependency Injection)
public class Messanger{
public showMessage_A(){
System.out.println(“Message A”);
}
public showMessage_B(){
System.out.println(“Message B”);
}
}
7. public class Messagener{
void showMessage(String message){
System.out.println(message);
}
}
showMessage(“Message A”); showCount(“Message B”);
DI (Dependency Injection)
8. DI (Dependency Injection)
public class Kenya_AA{
private int birthYear;
private int harvestYear;
}
public class CoffeMachine {
private Kenya_AA bean;
public CoffeMachine(Kenya_AA
bean){
this.bean = bean;
}
}
9. SOLID 원칙중 D (Dependency Inversion Principle) - 의존성 역전의 원칙
(SOLID 원칙 :객체지향 소프트웨어 설계의 근본 원칙, 디자인 패턴의 근본 원칙 객체지향 소프트웨어 설계 도구들의 근본이자 목적이 되는 원칙)
A. High-level modules should not depend on low-level modules. Both should depend on abstractions.
B. Abstractions should not depend on details. Details should depend on abstractions.
- Wikipedia
※ 모든 Parameter 가 Dependency는 아니다.
11. A. High-level modules should not depend on low-level modules. Both should depend on abstractions.
SOLID 원칙중 D (Dependency Inversion Principle)
public class CoffeeMachine {
private Kenya_AA bean = new Kenya_AA();
}
12. A. High-level modules should not depend on low-level modules. Both should depend on abstractions.
B. Abstractions should not depend on details. Details should depend on abstractions.
SOLID 원칙중 D (Dependency Inversion Principle)
public class CoffeeMachine {
private ICoffeBean bean;
public CoffeMachine(ICoffeBean
bean){
this.bean = bean;
}
public Interface ICoffeeBean {
void getBirthYear();
void
getHarvestYear();
}
14. DI (Dependency Injection)
public class CoffeeMachine {
private ICoffeBean bean;
public CoffeMachine(ICoffeBean
bean){
this.bean = bean;
}
- 생성자를 통한 DI
15. DI (Dependency Injection)
- Setter 를 통한 DI
public class CoffeeMachine {
private ICoffeBean bean;
public CoffeMachine() { }
public setCoffeMachine(ICoffeBean
bean){
this.bean = bean;
}
16. DI (Dependency Injection)
- 초기화 Interface 를 통한 DI
public class CoffeeMachine
implements
CoffeInjector {
private ICoffeBean bean;
public void injectCoffe(ICoffeBean bean){
this.bean = bean;
}
public interface CoffeInjector {
void injectCoffe(ICoffeBean bean);
}
18. 내가 누군가의 코드를 호출한다 - 라이브러리
누군가 나의 코드를 호출한다 - 프레임워크
IoC(Inversion of Control) - 제어의 역전
라이브러리 vs Framwork
19. 내가 생각하는 IoC Container의 등장배경
- DI 가 좋은건 알겠는데…
- 생성자에서 DI를 하면 Compile 타임에 보장은 되지만 생성자 Parameter 가 너
무 많아져서 문제..
- setter DI 를 하기엔 각각 setter 를 모두 만들어줘야하고 dependency가 올바로
들어온다는 보장은 없고…
- 매번 의존관계 (ex new Something()) 을 생성하는것도 귀찮고...
20. IOC Container 를 사용하지 않았을때 단점
- 손으로 일일이 DI 를 해야한다.
- Compile 타임에 DI 가 제대로 되었는지 확인하기 어렵다. (버그 확률 업)
- DI 를 안하면 확장성이 떨어짐
- 코드가 늘어난다.
21. Dagger 의 장점
- 컴파일 타임에서 DI 확인가능
- 동일 Instance 를 여러곳에서 많이쓴다면 중복 코드가 줄어든다.
- 테스트가 쉬워진다(?)
24. Dagger 를 쓰면 테스트가 쉬워진다(?) > DI 를 하면 Test가 가능해 진다.
public class AlramPresenter {
public Boolean isAlramTime(){
Date date = new 시스템시간();
if(date < 수요일){
return true;
} else if(date > 수요일){
return false;
}
}
}
public class AlramPresenterTest {
private AlramPresenter presenter;
@Before
public void setUp(){
presenter = new AlramPresenter();
}
@Test
public void before_수요일_Test(){
Boolean result =
presenter.isAlramTime();
}
@Test
public void after_수요일_Test(){
}
25. Dagger 를 쓰면 테스트가 쉬워진다(?) > DI 를 하면 Test가 가능해 진다.
public class AlramPresenter {
public Boolean isAlramTime(Date date){
String dateValue =
date.getDate();
if(dateValue < 수요일){
return true;
} else if(dateValue > 수요
일){
return false;
}
}
}
public class AlramPresenterTest {
private AlramPresenter presenter;
@Before
public void setUp(){
presenter = new AlramPresenter();
}
@Test
public void before_수요일_Test(){
Date date = mock(Date.class);
when(date.getDate()).thenReturn(“월요일”);
Boolean result = presenter.isAlramTime(date);
assertTrue(result);
}
}
26. Dagger 를 쓰면 테스트가 쉬워진다(?) > DI 를 하면 Test가 가능해 진다.
public class AlramPresenter {
public Boolean isAlramTime(Date date){
String dateValue =
date.getDate();
if(dateValue < 수요일){
return true;
} else if(dateValue > 수요
일){
return false;
}
}
}
public class AlramPresenterTest {
private AlramPresenter presenter;
@Before
public void setUp(){
presenter = new AlramPresenter();
}
@Test
public void after_수요일_Test(){
Date date = mock(Date.class);
when(date.getDate()).thenReturn(“금요일”);
Boolean result = presenter.isAlramTime(date);
assertFalse(result);
}
}
27. public class AlramPresenter {
IActivityView activity;
IRepository repository;
public void AlramPresenter(){
repository = RepositoryImpl();
}
// setter DI
public void setActivityView(IActivityView activity){
this.activity = activity;
}
public void appStart(){
FeedData feed = repository.getFeedList();
// generate viewmodel
...
}
public void refreshView(){
if(activityView != null){
acvitivyView.refreshView();
}
}
}
public class AlramPresenterTest {
private AlramPresenter presenter;
@Before
public void setUp(){
presenter = new AlramPresenter();
}
@Test
public void appStart_Test(){
presenter.appStart();
}
}
28. public class AlramPresenter {
IActivityView activity;
IRepository repository;
public void AlramPresenter(){
repository = RepositoryImpl();
}
// setter DI
public void setActivityView(IActivityView activity){
this.activity = activity;
}
public void appStart(){
FeedData feed = repository.getFeedList();
// generate viewmodel
...
}
public void refreshView(){
if(activityView != null){
acvitivyView.refreshView();
}
}
}
public class AlramPresenterTest {
private AlramPresenter presenter;
@Before
public void setUp(){
presenter = new AlramPresenter();
}
@Test
public void refreshViewTest(){
IActivityView activity = mock(IActivityView .class);
presenter.setActivityView(activity);
presenter.refreshView();
verify(activity.refreshView());
}
}
34. 질문
- Scope 는 Module / Component 에 모두 붙일수 있는가? (Component 는 class
에 Module 은 Provides 에 붙이던데..)
- Activity Scope이라고 명명하지만 사실 Component 호출 시점이 중요한것이 아
닌가..? Component 에 Activity Scope 이라고 적어놓고 Fragment 에서 생성하
면 결국 생성은 Fragment 에서 한것이니 Fragment 생명주기를 따르지 않을
까..?
- @Retention 은 무엇인가?