Upgrade to Pro — share decks privately, control downloads, hide ads and more …

Android 에서 Dagger를 쓰는 이유

Android 에서 Dagger를 쓰는 이유

Avatar for Kiyoung Lee

Kiyoung Lee

March 25, 2018

Other Decks in Programming

Transcript

  1. 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; } }
  2. 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는 아니다.
  3. 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(); }
  4. 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(); }
  5. DI (Dependency Injection) public class CoffeeMachine { private ICoffeBean bean;

    public CoffeMachine(ICoffeBean bean){ this.bean = bean; } - 생성자를 통한 DI
  6. DI (Dependency Injection) - Setter 를 통한 DI public class

    CoffeeMachine { private ICoffeBean bean; public CoffeMachine() { } public setCoffeMachine(ICoffeBean bean){ this.bean = bean; }
  7. 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); }
  8. 내가 누군가의 코드를 호출한다 - 라이브러리 누군가 나의 코드를 호출한다

    - 프레임워크 IoC(Inversion of Control) - 제어의 역전 라이브러리 vs Framwork
  9. 내가 생각하는 IoC Container의 등장배경 - DI 가 좋은건 알겠는데…

    - 생성자에서 DI를 하면 Compile 타임에 보장은 되지만 생성자 Parameter 가 너 무 많아져서 문제.. - setter DI 를 하기엔 각각 setter 를 모두 만들어줘야하고 dependency가 올바로 들어온다는 보장은 없고… - 매번 의존관계 (ex new Something()) 을 생성하는것도 귀찮고...
  10. IOC Container 를 사용하지 않았을때 단점 - 손으로 일일이 DI

    를 해야한다. - Compile 타임에 DI 가 제대로 되었는지 확인하기 어렵다. (버그 확률 업) - DI 를 안하면 확장성이 떨어짐 - 코드가 늘어난다.
  11. Dagger 의 장점 - 컴파일 타임에서 DI 확인가능 - 동일

    Instance 를 여러곳에서 많이쓴다면 중복 코드가 줄어든다. - 테스트가 쉬워진다(?)
  12. 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(){ }
  13. 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); } }
  14. 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); } }
  15. 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(); } }
  16. 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()); } }
  17. 질문 - Scope 는 Module / Component 에 모두 붙일수

    있는가? (Component 는 class 에 Module 은 Provides 에 붙이던데..) - Activity Scope이라고 명명하지만 사실 Component 호출 시점이 중요한것이 아 닌가..? Component 에 Activity Scope 이라고 적어놓고 Fragment 에서 생성하 면 결국 생성은 Fragment 에서 한것이니 Fragment 생명주기를 따르지 않을 까..? - @Retention 은 무엇인가?