본문 바로가기
Dart/Dart Programming language

[추가학습] Dart와 Flutter / State Management 개념 및 구현 (Bloc, Provider 등)

by Maccrey Coding 2024. 9. 17.
728x90
반응형

 

Flutter는 강력한 UI 툴킷으로 모바일, 웹, 데스크톱 애플리케이션을 효율적으로 개발할 수 있게 도와줍니다.

하지만 앱 개발에서 중요한 부분 중 하나는 상태 관리(State Management)입니다.

상태 관리는 애플리케이션의 데이터와 UI 상태를 어떻게 관리하고 업데이트할지 결정하는 과정입니다.

이번 블로그에서는 상태 관리의 개념과 함께, 대표적인 상태 관리 패턴인 BlocProvider를 초보자도 쉽게 이해할 수 있도록 설명하겠습니다.

1. 상태 관리란?

상태 관리는 애플리케이션에서 상태(state)를 추적하고 업데이트하는 과정을 의미합니다. 상태는 애플리케이션의 현재 데이터와 UI 상태를 포함하며, 예를 들어 로그인 여부, 장바구니의 아이템 수, 사용자 설정 등이 상태에 해당합니다.

 

Flutter에서 상태 관리는 UI와 비즈니스 로직을 연결하는 중요한 역할을 합니다.

상태 관리를 잘 하면 앱의 유지 보수성이 높아지고, 사용자 경험이 향상됩니다.

2. 상태 관리의 중요성

애플리케이션의 상태를 효과적으로 관리하는 것은 여러 가지 이유로 중요합니다.

  • 데이터 일관성 유지: 애플리케이션의 다양한 화면에서 데이터가 일관되게 유지됩니다.
  • UI 업데이트: 상태가 변경될 때 UI를 효율적으로 업데이트할 수 있습니다.
  • 유지 보수성: 코드의 가독성과 유지 보수성이 향상됩니다.

상태 관리를 통해 애플리케이션의 복잡성을 줄이고, 클린 코드를 유지할 수 있습니다.

3. 상태 관리 패턴 소개

상태 관리에는 여러 가지 패턴이 있으며, 그 중 BlocProvider는 매우 인기 있는 패턴입니다. 두 패턴 모두 Flutter 애플리케이션에서 상태를 효과적으로 관리할 수 있게 도와줍니다.

Bloc (Business Logic Component)

  • Bloc 패턴은 비즈니스 로직UI를 분리하는 방식입니다. Bloc은 비즈니스 로직을 담당하고, UI는 Bloc에서 제공하는 데이터를 표시합니다.
  • StreamSink를 사용해 데이터의 흐름을 관리합니다. UI에서 이벤트를 Bloc에 전달하고, Bloc은 이 이벤트를 처리하여 상태를 업데이트합니다.
  • Dart Streams를 활용하여 비동기 데이터 흐름을 처리합니다.

Provider

  • Provider는 Flutter에서 가장 많이 사용되는 상태 관리 라이브러리 중 하나입니다. Provider는 의존성 주입(Dependency Injection)과 상태 관리를 동시에 지원합니다.
  • ChangeNotifier를 사용하여 상태를 관리하고, 상태가 변경될 때 자동으로 UI를 업데이트합니다.
  • Provider는 코드의 가독성과 유지 보수성을 높이는 데 도움을 줍니다.

4. Bloc 패턴 이해하기

Bloc 패턴은 비즈니스 로직컴포넌트로 분리하여 UI와의 의존성을 줄입니다. 아래는 Bloc 패턴의 기본적인 구조입니다.

기본 구조

  1. Event: 사용자 입력이나 다른 이벤트를 정의합니다.
  2. State: 애플리케이션의 상태를 정의합니다.
  3. Bloc: 이벤트를 처리하고 새로운 상태를 생성하는 역할을 합니다.
import 'package:flutter/material.dart';
import 'package:flutter_bloc/flutter_bloc.dart';

// 이벤트 정의
abstract class CounterEvent {}
class IncrementEvent extends CounterEvent {}

// 상태 정의
abstract class CounterState {}
class CounterInitial extends CounterState {
  final int count;
  CounterInitial(this.count);
}

// Bloc 정의
class CounterBloc extends Bloc<CounterEvent, CounterState> {
  CounterBloc() : super(CounterInitial(0));

  @override
  Stream<CounterState> mapEventToState(CounterEvent event) async* {
    if (event is IncrementEvent) {
      final newCount = (state as CounterInitial).count + 1;
      yield CounterInitial(newCount);
    }
  }
}

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

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      home: BlocProvider(
        create: (context) => CounterBloc(),
        child: CounterPage(),
      ),
    );
  }
}

class CounterPage extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(title: Text('Bloc 예제')),
      body: Center(
        child: BlocBuilder<CounterBloc, CounterState>(
          builder: (context, state) {
            final count = (state as CounterInitial).count;
            return Column(
              mainAxisAlignment: MainAxisAlignment.center,
              children: [
                Text('Count: $count'),
                ElevatedButton(
                  onPressed: () {
                    BlocProvider.of<CounterBloc>(context).add(IncrementEvent());
                  },
                  child: Text('Increment'),
                ),
              ],
            );
          },
        ),
      ),
    );
  }
}

설명

  • CounterEvent와 CounterState는 Bloc 패턴의 기본 요소입니다.
  • CounterBloc은 이벤트를 처리하고 새로운 상태를 생성합니다.
  • BlocProvider는 Bloc을 위젯 트리에서 제공하며, BlocBuilder는 상태를 구독하고 UI를 업데이트합니다.

5. Provider 패턴 이해하기

Provider는 상태를 관리하고 의존성을 주입할 때 사용되는 간편한 라이브러리입니다.

기본적으로 ChangeNotifier를 사용하여 상태를 관리하며, 상태가 변경될 때 UI를 자동으로 업데이트합니다.

import 'package:flutter/material.dart';
import 'package:provider/provider.dart';

// ChangeNotifier 정의
class Counter with ChangeNotifier {
  int _count = 0;
  int get count => _count;

  void increment() {
    _count++;
    notifyListeners(); // 상태 변경을 알림
  }
}

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

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return ChangeNotifierProvider(
      create: (context) => Counter(),
      child: MaterialApp(
        home: CounterPage(),
      ),
    );
  }
}

class CounterPage extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    final counter = Provider.of<Counter>(context);

    return Scaffold(
      appBar: AppBar(title: Text('Provider 예제')),
      body: Center(
        child: Column(
          mainAxisAlignment: MainAxisAlignment.center,
          children: [
            Text('Count: ${counter.count}'),
            ElevatedButton(
              onPressed: () {
                counter.increment();
              },
              child: Text('Increment'),
            ),
          ],
        ),
      ),
    );
  }
}

설명

  • Counter 클래스는 ChangeNotifier를 상속받아 상태를 관리합니다.
  • ChangeNotifierProvider는 상태를 제공하고, Provider.of를 사용해 상태에 접근합니다.
  • notifyListeners()는 상태가 변경되었음을 알리고, UI를 자동으로 업데이트합니다.

 

상태 관리는 애플리케이션의 데이터와 UI 상태를 효율적으로 관리하는 중요한 과정입니다.

Flutter에서는 BlocProvider와 같은 다양한 상태 관리 패턴을 제공하여 개발자들이 효과적으로 상태를 관리할 수 있도록 돕습니다.

  • Bloc 패턴은 비즈니스 로직과 UI를 분리하고, 데이터의 흐름을 명확히 할 수 있습니다.
  • Provider 패턴은 상태 관리와 의존성 주입을 쉽게 구현할 수 있게 해줍니다.

상태 관리 패턴을 잘 이해하고 활용하면 애플리케이션의 구조를 더 깔끔하게 유지하고, 유지 보수성과 확장성을 높일 수 있습니다.

각 패턴의 장단점을 파악하고, 필요에 따라 적절한 패턴을 선택하여 효과적인 앱 개발을 시작해보세요!

구독!! 공감과 댓글은 저에게 큰 힘이 됩니다.

Starting Google Play App Distribution! "Tester Share" for Recruiting 20 Testers for a Closed Test.

 

Tester Share [테스터쉐어] - Google Play 앱

Tester Share로 Google Play 앱 등록을 단순화하세요.

play.google.com

728x90
반응형