728x90
📝 Flutter MVVM 패턴 정리
Flutter에서 애플리케이션을 개발할 때, 유지보수성과 확장성을 높이기 위해 MVVM (Model-View-ViewModel) 패턴을 적용할 수 있습니다.
이번 포스팅에서는 MVVM 패턴의 개념과 코드 예제를 통해 어떻게 구조화할 수 있는지 알아보겠습니다.
1️⃣ 앱 아키텍처란?
✅ 개념
- 애플리케이션의 전반적인 구조와 구성요소, 그리고 이들 간의 관계와 상호작용을 정의하는 설계 원칙입니다.
- 쉽게 말해, 앱을 구성하는 방법론을 의미합니다.
- 다양한 아키텍처 패턴이 존재하지만, 기본 원리는 동일합니다.
- 역할별로 레이어를 나누어 각 레이어가 자신의 역할에 집중하도록 설계.
- 이를 통해 수정, 테스트, 유지보수가 용이해집니다.
2️⃣ MVC 패턴을 사용하는 이유
✅ 개념
- 가장 기본적인 디자인 패턴 중 하나인 MVC(Model-View-Controller) 패턴은 UI와 데이터 로직을 분리하기 위해 사용됩니다.
- 하지만, MVC 패턴에서는 View와 Model 간의 강한 결합이 발생할 수 있어, 유지보수가 어려울 수 있습니다.
📌 MVC의 단점
- View와 Model이 강하게 연결되어 있어 재사용성이 떨어짐.
- 테스트가 어렵고 유지보수가 힘들어짐.
이를 해결하기 위해 등장한 패턴 중 하나가 MVVM입니다.
3️⃣ MVVM 패턴이란?
✅ 개념
MVVM(Model-View-ViewModel) 패턴은 UI(View)와 비즈니스 로직(Model)을 ViewModel을 통해 분리하여 유지보수성과 테스트 용이성을 높이는 패턴입니다.
📌 MVVM의 주요 구성 요소
컴포넌트 | 역할 |
Model | 데이터와 관련된 로직을 담당. 데이터베이스나 API 호출을 통해 데이터를 가져오고 저장. |
View | UI 화면을 담당. 사용자가 데이터를 보고, 입력을 ViewModel로 전달. |
ViewModel | UI 로직과 상태를 관리. View와 Model 간의 의존성을 줄이고 중개 역할을 수행. |
4️⃣ MVVM 패턴 예제 코드
📌 ViewModel 없이 작성한 코드 (main01.dart)
👉 View와 Model이 분리되지 않은 상태
import 'package:flutter/material.dart';
void main() {
runApp(MyApp01());
}
class MyApp01 extends StatelessWidget {
const MyApp01({super.key});
@override
Widget build(BuildContext context) {
return MaterialApp(
home: HomeView(),
);
}
}
// View
class HomeView extends StatefulWidget {
const HomeView({super.key});
@override
State<HomeView> createState() => _HomeViewState();
}
class _HomeViewState extends State<HomeView> {
// 이 예제에서는 _counter 를 모델로 바라볼 수 있다.
int _counter = 0;
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text('뷰 모델이 없는 코드'),
),
body: Column(
children: [
Text(
'${_counter}',
style: TextStyle(fontSize: 20, fontWeight: FontWeight.bold),
),
SizedBox(height: 12),
ElevatedButton(
onPressed: () {
setState(() {
_counter++;
});
},
child: Text('increment'),
)
],
),
);
}
}
📌 문제점
- View와 Model이 강하게 결합되어 있어 재사용이 어렵다.
- 상태 관리가 UI와 함께 작성되어 비즈니스 로직과 UI 로직이 분리되지 않음.
📌 MVVM 패턴 적용한 코드 (main02.dart)
👉 View와 Model을 분리하여 유지보수성 향상
import 'package:flutter/material.dart';
void main() {
runApp(MyApp02());
}
class MyApp02 extends StatelessWidget {
const MyApp02({super.key});
@override
Widget build(BuildContext context) {
return MaterialApp(
home: HomeView(),
);
}
}
// ViewModel
class HomeViewModel {
int _counter = 0;
// Getter
int get counter => _counter;
// 데이터를 변경하는 기능도 ViewModel이 가진다.
void incrementCounter() {
_counter++;
}
}
// View
class HomeView extends StatefulWidget {
const HomeView({super.key});
@override
State<HomeView> createState() => _HomeViewState();
}
class _HomeViewState extends State<HomeView> {
// 뷰는 뷰 모델만 바라보면 된다.
final HomeViewModel homeViewModel = HomeViewModel();
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text('MVVM 패턴 적용'),
),
body: Column(
children: [
Text(
'${homeViewModel.counter}',
style: TextStyle(fontSize: 20, fontWeight: FontWeight.bold),
),
SizedBox(height: 12),
ElevatedButton(
onPressed: () {
// UI는 비즈니스 로직을 직접 호출하지 않고, ViewModel을 통해 관리
setState(() {
homeViewModel.incrementCounter();
});
},
child: Text('increment'),
)
],
),
);
}
}
📌 개선된 점
- View와 Model이 분리되어 유지보수가 용이.
- ViewModel을 활용하여 UI 상태를 관리.
- 비즈니스 로직과 UI 로직을 분리하여 가독성이 좋아짐.
5️⃣ Model과 ViewModel의 차이점
컴포넌트역할
Model | 데이터 저장, 처리, 유효성 검사, 네트워크 및 데이터베이스 작업을 담당. |
ViewModel | View와 관련된 로직, 사용자 입력 처리, 로딩 상태 관리 등을 담당. |
📌 차이점
- Model은 데이터 중심, ViewModel은 UI와 관련된 상태 및 로직을 관리.
- ViewModel은 Model 데이터를 UI에 맞게 변환하여 제공.
📌 정리
✅ MVVM 패턴을 사용하면 좋은 점
✔ UI와 비즈니스 로직을 분리하여 유지보수성을 향상시킬 수 있다.
✔ ViewModel을 통해 UI 상태를 관리하여 코드의 가독성을 높일 수 있다.
✔ ViewModel을 활용하면 테스트가 용이해진다.
📌 MVC와 비교했을 때
- MVC는 View와 Model이 강하게 결합되어 유지보수가 어려움.
- MVVM은 ViewModel을 추가하여 UI와 비즈니스 로직을 명확히 분리.
📝 결론
MVVM 패턴은 Flutter에서 보다 효율적인 상태 관리와 구조적인 코드 작성을 가능하게 해줍니다.
상황에 따라 적절한 패턴을 선택하여 유지보수가 쉬운 코드를 작성해보세요! 🚀
'Flutter > Dart 언어' 카테고리의 다른 글
[Flutter] MVVM + 상태관리 (0) | 2025.02.05 |
---|---|
[Flutter] MVVM TodoList 만들기 (1) | 2025.02.05 |
[Flutter] 상태(State)의 종류 (0) | 2025.02.03 |
[Flutter] 상태란 뭘까? (2) | 2025.01.20 |
Dio 패키지 사용해 보기 (1) | 2025.01.14 |