[Flutter] MVVM + 상태관리

2025. 2. 5. 19:51·Flutter/Dart 언어
728x90
📝 Flutter Riverpod을 활용한 MVVM 패턴 정리

Flutter에서 Riverpod을 활용한 MVVM 패턴을 적용하면 상태 관리를 더욱 간결하고 효율적으로 할 수 있습니다.
이번 포스팅에서는 기본적인 MVVM 패턴을 Riverpod을 활용하여 개선하는 과정을 살펴보겠습니다.


1️⃣ MVVM 패턴이란?

👉 UI(View)와 비즈니스 로직(Model)을 ViewModel을 통해 분리하여 코드의 유지보수성과 테스트 용이성을 높이는 패턴
👉 기존의 setState() 방식 대신 Riverpod을 활용하여 전역 상태 관리


2️⃣ MVVM 패턴 구현

이번 구현에서는 Riverpod을 사용하여 MVVM 패턴을 적용할 것입니다.

📌 구조

  • Model (todo_item.dart): 데이터 모델을 정의.
  • ViewModel (todo_list_view_model.dart): 비즈니스 로직을 담당하고 Riverpod을 활용하여 상태 관리.
  • View (todo_list_view.dart): UI를 관리하며 ViewModel과 상호작용.

📌 Step 1: Model 생성 (todo_item.dart)

👉 할 일(Todo) 항목을 정의하는 데이터 모델

// Model
// 1. 우리가 관리 하고 싶은 데이터 (창고 안에 넣을 상품)
class TodoItem {
  String title;
  bool isDone;

  TodoItem({required this.title, this.isDone = false});

  // 상태 변경 시 불변 객체를 유지하기 위한 copyWith 메서드 추가
  TodoItem copyWith({String? title, bool? isDone}) {
    return TodoItem(
      title: title ?? this.title,
      isDone: isDone ?? this.isDone,
    );
  }
}

 

📌 역할

  • title: 할 일 제목.
  • isDone: 완료 여부.
  • 불변 객체 원칙을 유지하기 위해 copyWith 메서드 추가.

📌 Step 2: ViewModel 생성 (todo_list_view_model.dart)

👉 비즈니스 로직을 담당하며, 상태를 Riverpod으로 관리

import 'package:flutter_riverpod/flutter_riverpod.dart';
import '../models/todo_item.dart';

// ViewModel - 상태 관리 및 비즈니스 로직을 담당
class TodoListViewModel extends Notifier<List<TodoItem>> {
  @override
  List<TodoItem> build() {
    return [];
  }

  // 할 일 추가
  void addItem(String title) {
    state = [...state, TodoItem(title: title)];
  }

  // 할 일 완료 상태 변경 (불변 객체 유지)
  void toggleItem(TodoItem todo) {
    state = state
        .map((item) => item == todo ? item.copyWith(isDone: !item.isDone) : item)
        .toList();
  }
}

// Provider - ViewModel을 Riverpod 상태 관리에 등록
final todoListViewModelProvider =
    NotifierProvider<TodoListViewModel, List<TodoItem>>(
  () => TodoListViewModel(),
);

 

📌 개선된 점

  • Riverpod을 활용하여 상태 관리 (NotifierProvider 사용).
  • state = [...state, TodoItem(title: title)]; → 기존 리스트를 변경하지 않고 새로운 객체를 생성하여 업데이트.
  • toggleItem에서 불변 객체(copyWith)를 유지하여 안전한 상태 관리.

📌 Step 3: View 생성 (todo_list_view.dart)

👉 ViewModel을 사용하여 UI를 업데이트하는 역할

import 'package:flutter/material.dart';
import 'package:flutter_riverpod/flutter_riverpod.dart';
import '../models/todo_item.dart';
import '../view_models/todo_list_view_model.dart';

class TodoListView extends ConsumerWidget {
  final TextEditingController _controller = TextEditingController();

  TodoListView({super.key});

  @override
  Widget build(BuildContext context, WidgetRef ref) {
    // ViewModel의 상태를 감시 (자동 업데이트)
    final todos = ref.watch(todoListViewModelProvider);
    // ViewModel 인스턴스를 가져와서 메서드 실행
    final todoNotifier = ref.read(todoListViewModelProvider.notifier);

    return Flexible(
      child: Column(
        children: [
          Padding(
            padding: const EdgeInsets.all(16.0),
            child: TextField(
              controller: _controller,
              decoration: InputDecoration(
                hintText: 'Enter todo item...',
                suffixIcon: IconButton(
                  onPressed: () {
                    if (_controller.text.isNotEmpty) {
                      todoNotifier.addItem(_controller.text);
                      _controller.clear();
                    }
                  },
                  icon: Icon(Icons.add),
                ),
              ),
            ),
          ),
          SizedBox(height: 16.0),
          Expanded(
            child: ListView.builder(
              itemCount: todos.length,
              itemBuilder: (context, index) {
                final TodoItem item = todos[index];
                return ListTile(
                  title: Text(item.title),
                  trailing: Checkbox(
                    value: item.isDone,
                    onChanged: (value) {
                      todoNotifier.toggleItem(item);
                    },
                  ),
                );
              },
            ),
          )
        ],
      ),
    );
  }
}

 

📌 개선된 점

  • ConsumerWidget을 사용하여 Riverpod 상태를 구독.
  • ref.watch(todoListViewModelProvider) → 자동으로 UI 업데이트.
  • View에서는 ViewModel의 메서드를 호출하는 역할만 수행.

📌 Step 4: 앱 실행 (main.dart)

👉 ProviderScope를 사용하여 Riverpod을 활성화하고 TodoListView를 표시

import 'package:flutter/material.dart';
import 'package:flutter_riverpod/flutter_riverpod.dart';
import 'package:flutter_statement_v01/_mvvm/_04/views/todo_list_view.dart';

void main() {
  runApp(ProviderScope(child: TodoApp()));
}

class TodoApp extends StatelessWidget {
  const TodoApp({super.key});

  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      debugShowCheckedModeBanner: false,
      home: SafeArea(
        child: Scaffold(
          appBar: AppBar(
            title: const Text('TodoList'),
          ),
          body: TodoListView(),
        ),
      ),
    );
  }
}

 

📌 역할

  • ProviderScope를 추가하여 Riverpod 상태 관리 활성화.
  • TodoListView()를 Scaffold 내에 배치하여 UI 구성.

📌 MVVM 패턴 적용 후 개선된 점

개선 사항 기존 방식 (setState()) Riverpod 적용 방식
상태 관리 setState()를 통해 직접 관리 NotifierProvider를 활용하여 전역 상태 관리
비즈니스 로직 위치 View에서 직접 관리 ViewModel에서 관리
UI 업데이트 setState() 호출 시 전체 위젯 재빌드 필요한 부분만 자동 업데이트
불변 객체 유지 기존 객체를 직접 수정 copyWith을 활용하여 상태 변경

 


📝 결론

✅ Riverpod을 활용한 MVVM 패턴의 장점

✔ UI와 비즈니스 로직을 완전히 분리하여 유지보수성이 향상됨.
✔ Riverpod을 통해 전역 상태를 효율적으로 관리하여 코드의 가독성이 향상됨.
✔ View는 UI를 렌더링하는 역할만 수행하고, ViewModel에서 모든 상태 관리를 담당하여 구조가 깔끔해짐.
✔ 불변 객체 원칙을 유지하여 예측 가능한 상태 관리 가능.

👉 Riverpod을 활용하면 더 유지보수하기 좋은 구조로 Flutter 애플리케이션을 개발할 수 있습니다! 🚀


MVVM 패턴이 궁금하다면??

 

[Flutter] MVVM TodoList 만들기

📝 Flutter MV 패턴 & MVVM 패턴 정리Flutter에서 MV (Model-View) 패턴과 MVVM (Model-View-ViewModel) 패턴을 활용하여 코드의 유지보수성과 가독성을 높일 수 있습니다.이번 포스팅에서는 MV → MVVM으로 발전하는

seohong.tistory.com

 

 

 

[Flutter] MVVM 패턴에 대해서 알아 보자

📝 Flutter MVVM 패턴 정리Flutter에서 애플리케이션을 개발할 때, 유지보수성과 확장성을 높이기 위해 MVVM (Model-View-ViewModel) 패턴을 적용할 수 있습니다.이번 포스팅에서는 MVVM 패턴의 개념과 코드

seohong.tistory.com

 

'Flutter > Dart 언어' 카테고리의 다른 글

[Flutter] MVVM TodoList 만들기  (1) 2025.02.05
[Flutter] MVVM 패턴에 대해서 알아 보자  (0) 2025.02.05
[Flutter] 상태(State)의 종류  (0) 2025.02.03
[Flutter] 상태란 뭘까?  (2) 2025.01.20
Dio 패키지 사용해 보기  (1) 2025.01.14
'Flutter/Dart 언어' 카테고리의 다른 글
  • [Flutter] MVVM TodoList 만들기
  • [Flutter] MVVM 패턴에 대해서 알아 보자
  • [Flutter] 상태(State)의 종류
  • [Flutter] 상태란 뭘까?
공돌이 출신 개발자
공돌이 출신 개발자
공돌이 출신 개발자입니다
  • 공돌이 출신 개발자
    공돌이 출신 개발자
    공돌이 출신 개발자
  • 전체
    오늘
    어제
    • 분류 전체보기 (124)
      • Database (0)
        • SQL (0)
        • 1일 1쿼리 (9)
      • Flutter (40)
        • Dart 언어 (18)
        • App (22)
      • Git (0)
      • Http 기초 지식 (14)
      • HTML5 & CSS3 (0)
      • Java (33)
      • JSP (0)
      • JavaScript (0)
      • Linux (0)
      • MSA (0)
      • Project (0)
      • React (0)
      • Spring (19)
      • 설치 메뉴얼 (1)
      • [Flutter] 프로젝트 (눈길) (8)
        • 작업일지 (8)
  • 블로그 메뉴

    • 홈
    • 태그
    • 방명록
  • 링크

    • GitHub
  • 공지사항

  • 인기 글

  • 태그

    블로그 만들기
    프로그래밍
    공부
    dart
    코딩
    앱 개발
    안드로이드 앱 개발
    SQLD
    회원가입
    데이터
    JAVA 기초
    SQL
    앱개발
    객체
    안드로이드
    클래스
    로그인
    Android
    플러터
    HTTP
    android studio
    메서드
    jsp
    spring boot
    flutter
    프로젝트
    객체지향
    Java
    개발
    1일1쿼리
  • 최근 댓글

  • 최근 글

  • hELLO· Designed By정상우.v4.10.2
공돌이 출신 개발자
[Flutter] MVVM + 상태관리
상단으로

티스토리툴바