Hilt 를 활용한 로그인 스코프 관리하기
unsplash.com안녕하세요. NaverFinancial 앱 개발팀의 심명표 입니다.
Disclaimer❗️
이 글은 Hilt나 Dagger의 기본 사용법에 대해 다루지는 않지만 관련해서 참고할 링크를 본문에 기록하였습니다.
DI 가 무엇인지 이미 알고 있고 Custom Component의 사용에 대해서 바로 보고 싶으신 분은 Custom Component로 바로 스크롤 해도 됩니다.
DI (Dependency Injection)
의존성 주입(DI)이란 무엇이며 왜 사용할까요? 우리가 객체지향으로 어떤 프로그램을 디자인한다고 생각해 봅시다. 아마도 모든 기능을 제공하는 거대한 단일 클래스를 만들어 프로그램을 완성할 수도 있지만 누구도 이런 식으로 프로그램을 만들지는 않습니다. 이런 식의 설계는 본인과 동료 그리고 후임자를 괴롭게 만드는 행동입니다 (물론 오직 나만 다룰 수 있는 프로그램을 만들어 조직에서 대체불가의 직원이 될 수도 있겠죠. #유지 보수하기 어렵게 코딩하는 방법
).
그래서 우리는 나와 내 동료의 오후와 행복한 휴일을 위해서 객체지향 디자인 원칙에 따라서 적절하게 클래스를 설계하고 클래스 간의 관계를 정의합니다 (SOLID 원칙에 대해 그림으로 설명하는 재미있는 미디엄 글이 있습니다).
현실 세계를 모델링 한 객체지향은 프로그램 세계에는 맞지 않으며 실패한 패러다임이라는 의견도 있지만 이는 지금 이야기하고자 하는 것과는 다른 주제이며, 이 의견 역시 코드를 한 덩어리로 만들어도 된다는 말은 당연히 아닙니다.
여러분이 각 클래스를 역할에 따라 세분화하여 디자인하면 클래스 간에는 참조 관계가 생깁니다. 우리는 이것을 의존성이라 부릅니다. 여러분이 프로그램으로 냉온 정수기를 디자인한다고 가정해 봅시다. 정수기 클래스는 물을 데우기 위한 가열기, 물을 냉각하기 위한 냉각기, 그리고 본연의 기능인 물을 정화하기 위한 필터 등의 내부 부속품들이 필요합니다. 이 부속품들은 모두 냉온 정수기의 의존 객체라고 할 수 있습니다.
이렇게 한 객체(정수기)가 의존하는 객체들(부속)을 개별적으로 정의하고, 각 부속의 기능을 인터페이스로 정의하면 우리는 매우 유연하고 테스트가 용이한 정수기 클래스를 갖게 됩니다. 예를 들면 다음과 같이 정수기 클래스 WaterPurifier 클래스를 정의하면 우리는 다양한 타입의 가열기, 냉각기, 필터 등을 갖는 정수기를 생성할 수 있습니다.
https://medium.com/media/2cd9be333fb7383af4054290cef7c698/href위 샘플 코드에서 WaterTank, Heater, Cooler 등은 모두 각 기능이 정의된 인터페이스이므로 어떤 구현체라도 프로토콜(인터페이스)만 지키면 생성자로 전달될 수 있습니다. 물론 아주 팬시한 구현체가 전달되면 정수기의 성능이 좋아지겠지만 가격 또한 올라가겠죠
? 그리고 이렇게 인터페이스를 클래스 생성자로 전달받도록 구현하여 얻게 된 유연성은 이 클래스를 테스트 친화적으로 만들어 줍니다. 클래스를 테스트할 때 각종 부속품 인터페이스의 구현체로 Mock 객체를 전달하여 다양한 상황에서 정수기의 상태를 테스트해 볼 수 있습니다.
이 정수기 클래스를 생성하면서 각종 부속품의 구현체들을 직접 생성하여 주입하는 방식을 수동 주입(Manual Injection)이라고 합니다. 이처럼 의존성 주입을 하기 위해서 특정 툴이 필요한 것은 아니며 원한다면 직접 구현하는 것도 가능합니다. 하지만 의존성 관리 도구를 사용하면 보다 편리하고 안정적으로 의존성을 주입하고 관리할 수 있습니다. 의존성 관리 도구를 사용하여 얻을 수 있는 장점으로는 손쉬운 의존 오브젝트들의 수명(Scope) 관리를 예로 들 수 있습니다. 여러분이 의존성 주입 방식으로 프로그램을 만들 때, 어떤 의존성들은 애플리케이션과 동일한 스코프를 갖지만 다른
).
그래서 우리는 나와 내 동료의 오후와 행복한 휴일을 위해서 객체지향 디자인 원칙에 따라서 적절하게 클래스를 설계하고 클래스 간의 관계를 정의합니다 (SOLID 원칙에 대해 그림으로 설명하는 재미있는 미디엄 글이 있습니다).
현실 세계를 모델링 한 객체지향은 프로그램 세계에는 맞지 않으며 실패한 패러다임이라는 의견도 있지만 이는 지금 이야기하고자 하는 것과는 다른 주제이며, 이 의견 역시 코드를 한 덩어리로 만들어도 된다는 말은 당연히 아닙니다.
여러분이 각 클래스를 역할에 따라 세분화하여 디자인하면 클래스 간에는 참조 관계가 생깁니다. 우리는 이것을 의존성이라 부릅니다. 여러분이 프로그램으로 냉온 정수기를 디자인한다고 가정해 봅시다. 정수기 클래스는 물을 데우기 위한 가열기, 물을 냉각하기 위한 냉각기, 그리고 본연의 기능인 물을 정화하기 위한 필터 등의 내부 부속품들이 필요합니다. 이 부속품들은 모두 냉온 정수기의 의존 객체라고 할 수 있습니다.
이렇게 한 객체(정수기)가 의존하는 객체들(부속)을 개별적으로 정의하고, 각 부속의 기능을 인터페이스로 정의하면 우리는 매우 유연하고 테스트가 용이한 정수기 클래스를 갖게 됩니다. 예를 들면 다음과 같이 정수기 클래스 WaterPurifier 클래스를 정의하면 우리는 다양한 타입의 가열기, 냉각기, 필터 등을 갖는 정수기를 생성할 수 있습니다.
https://medium.com/media/2cd9be333fb7383af4054290cef7c698/href위 샘플 코드에서 WaterTank, Heater, Cooler 등은 모두 각 기능이 정의된 인터페이스이므로 어떤 구현체라도 프로토콜(인터페이스)만 지키면 생성자로 전달될 수 있습니다. 물론 아주 팬시한 구현체가 전달되면 정수기의 성능이 좋아지겠지만 가격 또한 올라가겠죠
? 그리고 이렇게 인터페이스를 클래스 생성자로 전달받도록 구현하여 얻게 된 유연성은 이 클래스를 테스트 친화적으로 만들어 줍니다. 클래스를 테스트할 때 각종 부속품 인터페이스의 구현체로 Mock 객체를 전달하여 다양한 상황에서 정수기의 상태를 테스트해 볼 수 있습니다.
이 정수기 클래스를 생성하면서 각종 부속품의 구현체들을 직접 생성하여 주입하는 방식을 수동 주입(Manual Injection)이라고 합니다. 이처럼 의존성 주입을 하기 위해서 특정 툴이 필요한 것은 아니며 원한다면 직접 구현하는 것도 가능합니다. 하지만 의존성 관리 도구를 사용하면 보다 편리하고 안정적으로 의존성을 주입하고 관리할 수 있습니다. 의존성 관리 도구를 사용하여 얻을 수 있는 장점으로는 손쉬운 의존 오브젝트들의 수명(Scope) 관리를 예로 들 수 있습니다. 여러분이 의존성 주입 방식으로 프로그램을 만들 때, 어떤 의존성들은 애플리케이션과 동일한 스코프를 갖지만 다른

