Stacked - Services

김례원·2025년 7월 6일

Flutter

목록 보기
8/12
post-thumbnail

🧩 Stacked의 Service란?

Service는 비즈니스 로직을 처리하는 독립적인 클래스로, ViewModel이나 View와 분리되어 있습니다.
API 호출, 로컬 저장소 접근, 인증 처리 등 다양한 로직을 Service에 분리시켜 앱을 더 구조적이고 유지보수하기 쉽게 만들어줍니다.


✅ 왜 Service를 사용하는가?

  • ViewModel이 UI 상태 관리에만 집중할 수 있음
  • 비즈니스 로직을 여러 ViewModel 간에 재사용 가능
  • 테스트가 훨씬 쉬워짐 (ViewModel과 분리되어 mock 가능)
  • 서비스는 앱 전역에서 싱글톤으로 관리됨

🧱 서비스 만들기 예시

class CounterService {
  int _counter = 0;

  int get counter => _counter;

  void incrementCounter() {
    _counter++;
  }
}

이렇게 하면 로직이 ViewModel에서 분리되어 독립적으로 관리됩니다.


🔧 서비스 등록 (setupLocator)

서비스를 사용하려면 앱 시작 시 등록해야 합니다.

final locator = StackedLocator.instance;

void setupLocator() {
  locator.registerLazySingleton(() => CounterService());
}
  • registerLazySingleton: 첫 호출 시 한 번만 생성
  • setupLocator()main.dart에서 호출되어야 함
void main() {
  setupLocator();
  runApp(MyApp());
}

📦 서비스 사용하기 (ViewModel에서)

final _counterService = locator<CounterService>();

void increase() {
  _counterService.incrementCounter();
  notifyListeners();
}

이제 ViewModel에서 서비스를 가져와서 사용할 수 있습니다.


🔄 상태가 있는 서비스 → ViewModel에서 반응하려면?

상태가 자주 바뀌는 서비스(_counter 등)를 ViewModel에서 실시간 반영하고 싶을 때는 ReactiveViewModel을 사용합니다.

class HomeViewModel extends ReactiveViewModel {
  final _counterService = locator<CounterService>();

  
  List<ListenableServiceMixin> get listenableServices => [_counterService];
}

→ 이 경우, 서비스의 값이 바뀌면 ViewModel이 자동으로 감지하고 notifyListeners()를 호출합니다.

CounterServiceListenableServiceMixin을 믹스인해야 합니다.

class CounterService with ListenableServiceMixin {
  int _counter = 0;

  int get counter => _counter;

  void incrementCounter() {
    _counter++;
    notifyListeners(); // mixin에서 제공
  }
}

🧪 테스트 시 mock 서비스 등록

locator.registerSingleton<CounterService>(FakeCounterService());

→ 기존 서비스를 Fake로 대체하여 테스트에 사용 가능


✅ 정리

항목설명
Service비즈니스 로직 담당 클래스
setupLocator서비스 등록 함수
locator()서비스 인스턴스를 가져오는 함수
registerLazySingleton호출 시 1회만 생성하여 재사용
ReactiveViewModel + ListenableServiceMixin상태 변경 자동 감지 & UI 반영
테스트Mock/Fake로 서비스 대체 가능

💡 요점 정리

  • Service는 비즈니스 로직을 담는 독립 모듈입니다.
  • ViewModel과 분리되어 유지보수와 테스트가 쉬워집니다.
  • setupLocator를 통해 등록하고, 전역에서 locator<>()로 사용합니다.
  • 상태가 변하는 서비스는 ListenableServiceMixin을 써서 ViewModel에서 자동 감지할 수 있습니다.

알아두면 좋을 내용

  • FirebaseService, APIService, AuthService 등 실전용 서비스 구조

출처 : Stacked 공식 문서 - Services

profile
분야를 가리지 않는 개발자

0개의 댓글