Flutter EventBus로 결합도 낮추기: 페이지 간 업데이트 감지하기

2
post-thumbnail

결합성 낮추기: Flutter EventBus로 페이지 간 업데이트 감지하기

Flutter 앱에서 push, pop 등으로 페이지 전달하는 코드 없이 Tab 등으로 위치 다른 페이지가 있을 때, 한 페이지에서 일어난 변화를 다른 페이지가 어떻게 알 수 있을까요?

좌측

  • 상황: A1 -> A2 페이지 이동으로 이어진 상황
  • 데이터 전달: push, pop은 페이지 통해 데이터 전달 또는 후 액션 처리 하기 쉽죠

우측

  • 상황: A1 -> A2 페이지 이동으로 이어져있고, B1은 다른 탭 페이지
    (A2와 B1은 직접적인 페이지 연결 없음)
  • 데이터 전달: push, pop으로 연결되어있는 페이지가 아닌 상황에서 다른 탭의 B1 페이지에서 어떻게 데이터를 전달 또는 후 액션을 할 수 있을까요? 🤔

전역적으로 처리 등 다양한 방법이 있겠지만 그 중에서도 EventBus를 이용하면 이런 문제를 훨씬 간단하게 해결할 수 있습니다.

오늘은 Flutter에서 EventBus를 활용해 결합성을 낮추고 페이지 간 소통을 쉽게 만드는 방법을 알아보겠습니다.

EventBus란?

먼저, EventBus가 무엇인지 짚고 넘어가죠.

간단하게 말해 EventBus는 애플리케이션 내의 다양한 컴포넌트들이 이벤트를 통해 서로 통신할 수 있게 해주는 도구입니다. 이는 특히 서로 직접적인 참조가 없는 컴포넌트 간의 결합성을 낮출 때 유용합니다.


EventBus 구현하기

자, 이제 예제 코드와 함께 EventBus의 구현을 살펴봅시다.

event_bus.dart

import 'dart:async';

class EventBus {
  static final EventBus _instance = EventBus._internal();
  factory EventBus() => _instance;
  EventBus._internal();

  final _eventController = StreamController<dynamic>.broadcast();

  Stream<T> on<T>() =>
      _eventController.stream.where((event) => event is T).cast<T>();

  void fire(event) => _eventController.add(event);

  void dispose() => _eventController.close();
}

위 코드는 EventBus의 기본적인 구조를 보여줍니다. 각 부분을 하나씩 설명해볼게요:

  1. 싱글톤 패턴: EventBus 클래스는 싱글톤 패턴으로 구현되었습니다. 이는 어플리케이션 전역에서 하나의 인스턴스만 사용되도록 보장합니다.

  2. StreamController: _eventController는 이벤트를 관리하기 위해 사용됩니다. .broadcast()를 사용해 여러 리스너가 동일한 스트림을 구독할 수 있게 합니다.

  3. on() 메서드: 특정 타입의 이벤트를 필터링해서 스트림으로 반환합니다. 이를 통해 특정 이벤트 타입만을 구독할 수 있습니다.

  4. fire(event) 메서드: 새로운 이벤트를 스트림에 추가합니다.

  5. dispose() 메서드: 더 이상 EventBus가 필요 없을 때 스트림을 닫습니다.


이벤트 모델 정의하기

이제 EventBus에서 사용할 이벤트 모델을 정의해봅시다. 여기서는 블로그가 생성되는 이벤트를 예제로 들어 설명하겠습니다.

events.dart

class BlogCreatedEvent {
  final String blogId;
  BlogCreatedEvent(this.blogId);
}

간단하죠? BlogCreatedEvent 클래스는 블로그 생성 시 이벤트를 트리거하기 위한 모델을 정의합니다.

파일 구조는 아래와 같이 참고하세요 !

project_lib/
├── core/
│   ├── event_bus/
│   │   ├── event_bus.dart
│   │   └── events.dart
│   └── utils/
│       └── ...
├── data/
│   └── ...
└── presentation/
    └── ...

EventBus 활용하기

EventBus와 이벤트 모델이 준비되었으니, 실제로 이를 어떻게 활용하는지 살펴봅시다.

  1. 블로그 생성 페이지에서 이벤트를 트리거하는 부분입니다:
import 'event_bus.dart';
import 'events.dart';

void createBlog() {
  try {
    // 블로그 생성 로직
  } catch (e) {
    // 에러 처리
  } finally {
    EventBus().fire(BlogCreatedEvent(blogId));
  }
}

블로그가 성공적으로 생성되었을 때 EventBus().fire(BlogCreatedEvent(blogId));를 호출하여 이벤트를 발생시킵니다.

  1. 그리고 블로그 목록 페이지에서 이 이벤트를 구독해서 반응하는 부분입니다:
import 'event_bus.dart';
import 'events.dart';

class BlogListViewModel with ChangeNotifier {
  BlogListViewModel() {
    EventBus().on<BlogCreatedEvent>().listen(_onBlogCreated);
  }

  void _onBlogCreated(BlogCreatedEvent event) {
    // 목록 새로고침 로직
    fetchBlogs(isForce: true);
  }
  
  
  void dispose() {
    EventBus().dispose();
    super.dispose();
  }
}

여기서는 EventBus().on<BlogCreatedEvent>().listen(_onBlogCreated);를 통해 특정 이벤트 타입을 구독하고, 이벤트 발생 시 블로그 목록을 새로고침합니다.

마지막으로, 메모리 누수를 방지하기 위해 dispose() 메서드 내에서 EventBus의 dispose()를 호출해 스트림을 닫습니다.

결론

EventBus를 이용한 이 패턴의 장점은 페이지 간 결합성을 낮추면서도 서로의 상태 변화를 쉽게 감지하고 반응할 수 있다는 점입니다. Flutter 프로젝트에서 여러 페이지가 상호작용해야 하지만 서로 직접적으로 접근하지 않기를 원할 때, EventBus는 탁월한 해결책이 될 수 있습니다.

이제 여러분도 EventBus를 활용해 더 확장성 높고 유지보수하기 쉬운 Flutter 애플리케이션을 만들어보세요! 🍀

🔥 해당 포스팅은 Dev.POST 도움을 받아 작성되었습니다.

profile
🔥 코드 과정 중 자연스레 쌓인 경험과 지식을 기술 블로그로 작성해줍니다.

0개의 댓글