Flutter 의존성 주입(Dependency Injection) 쉽게 이해하기

Baek Dong Hyun·2025년 1월 22일
1

1. 의존성 주입이란?

쉽게 말해, 클래스가 직접 필요한 객체를 만들지 않고, 외부에서 받아오는 방식입니다.

예를 들어 커피를 만들 때 바리스타(클래스)가 직접 원두를 사고 물을 준비하는 게 아니라, 매니저(의존성 주입 시스템)가 미리 준비해 준 원두와 물을 받는다고 생각하면 됩니다.

의존성을 직접 생성하는 경우 (나쁜 방식)

class CoffeeMaker {
  final CoffeeBeans beans = CoffeeBeans();
  final Water water = Water();
  
  void brew() {
    print('커피 만들기');
  }
}

위의 코드에서는 CoffeeMaker가 원두와 물을 직접 생성하기 때문에, 만약 새로운 원두로 변경하려면 CoffeeMaker 클래스도 수정해야 합니다.

의존성 주입 적용 (좋은 방식)

class CoffeeMaker {
  final CoffeeBeans beans;
  final Water water;
  
  CoffeeMaker(this.beans, this.water);
  
  void brew() {
    print('커피 만들기');
  }
}

이렇게 하면 외부에서 객체를 주입해주므로, 커피메이커는 커피 만들기에만 집중할 수 있습니다.


2. 의존성 주입을 왜 사용해야 할까?

  1. 유지보수가 용이함

    • 필요한 객체를 교체할 때 코드 변경이 최소화됨.
  2. 테스트가 쉬워짐

    • 실제 객체 대신 Mock 객체(테스트용)를 주입할 수 있어 테스트가 용이함.
  3. 코드 재사용성이 높아짐

    • 다양한 환경에서 같은 객체를 주입하여 사용 가능.
  4. 의존성 관리가 편리함

    • 앱이 커질수록 객체 간 의존성을 효과적으로 관리할 수 있음.

3. Flutter에서 의존성 주입 방법과 추천 패키지

Flutter에서 DI를 적용할 수 있는 몇 가지 방법이 있습니다.

1) GetIt (서비스 로케이터 패턴)

GetIt은 객체를 전역적으로 등록하고 필요할 때 가져다 쓰는 방법입니다.

final getIt = GetIt.instance;

void setup() {
  getIt.registerSingleton<ApiService>(ApiService());
}

void main() {
  setup();
  runApp(MyApp());
}

class MyApp {
  final apiService = getIt<ApiService>();
}
  • 장점: 쉽고 빠르게 적용 가능, 코드 간결.
  • 단점: 전역적으로 의존성을 관리하므로 남용하면 유지보수가 어려울 수 있음.

2) Injectable + GetIt (코드 자동 생성)

Injectable은 GetIt을 더 체계적으로 사용할 수 있도록 도와주는 패키지입니다.


class CoffeeMaker {
  final CoffeeBeans beans;
  CoffeeMaker(this.beans);
}
  • 장점: 자동 코드 생성으로 생산성 향상, 대규모 프로젝트에 적합.
  • 단점: 설정이 까다로움, 빌드 속도가 느려질 수 있음.

3) Riverpod (상태 관리 + DI)

Riverpod은 상태 관리와 의존성 주입을 함께 처리할 수 있는 패키지입니다.

final coffeeProvider = Provider<CoffeeMaker>((ref) {
  return CoffeeMaker(beans: CoffeeBeans());
});
  • 장점: 상태 관리와 DI를 한 번에 해결, 타입 안정성 보장.
  • 단점: 배우는 데 시간이 필요할 수 있음.

4) Provider (Flutter 기본 DI 방식)

Provider는 Flutter에서 기본적으로 제공하는 DI 패턴으로, 위젯 트리를 통해 의존성을 제공할 수 있습니다.

class MyApp extends StatelessWidget {
  
  Widget build(BuildContext context) {
    return Provider<ApiService>(
      create: (context) => ApiService(),
      child: HomeScreen(),
    );
  }
}
  • 장점: 공식 Flutter 지원, 쉬운 사용.
  • 단점: 위젯 트리를 기반으로 작동하여 전역 관리가 어려울 수 있음.

4. 어떤 패키지를 선택해야 할까?

  • 소규모 프로젝트 (빠른 개발 필요)GetIt 추천.
  • 대규모 프로젝트 (유지보수와 확장성 중요)Injectable + GetIt 추천.
  • 상태 관리와 의존성을 함께 처리하려면Riverpod 추천.
  • 간단한 의존성 주입Provider 추천.

5. 결론

의존성 주입은 프로젝트의 유지보수성, 확장성, 테스트 용이성을 크게 향상시킬 수 있습니다.
프로젝트의 크기와 요구사항에 따라 적절한 DI 방법을 선택하는 것이 중요합니다.

chat gpt 와 구글링을 통해 정리했습니다.

profile
안녕하세요.

0개의 댓글