[Flutter] MVC 디자인 패턴

hodu·2023년 4월 10일
1

Flutter

목록 보기
8/30
post-thumbnail

MVC패턴을 사용하는 이유

MVC패턴이나 MVVM 패턴은 인터페이스, 데이터, 데이터 제어에 사용되는 소프트웨어 디자인 패턴이다. Model, View Model, View는 각자의 역할을 하며, 팀 단위 프로젝트에 큰 도움이 된다.

만일, 한 페이지 안에 변수, 함수, 위젯을 한번에 선언하게 되면, dart파일의 처음부터 끝까지 읽으며 수정해야 되기 때문에, 많은 시간이 소요될 것이다.

하지만, 각 Model, ViewModel, View로 분리한다면 필요한 부분만 가서 변경할 수 있다. 이러면 코드를 전부 읽지 않아도 특정 위치에 변경 지점이 있다는 것을 인지할 수도 있고, 접근 시간이 단축될 것이다.

Model, View, Controller 역할

  • Model은 데이터를 저장하는 클래스이다.(ex. 계정 정보, 영화 정보 등)
  • Controller(또는 ViewModel)는 사용자 입력에 대한 응답으로 Model의 데이터를 업데이트 한다.
  • View는 앱의 데이터를 보여주는 UI이다.


API 셋팅

API 통신은 Restful Api를 사용하며 디렉터리를 따로 구성한다. 그 이유는 개인적으로 API 함수(Post, Get, Delete 등)을 한곳에 모아두면 수정이 수월하기 때문이다.

API를 통해 얻은 데이터는 with ChangeNotifier를 포함한 클래스에 저장하여 사용한다.

파일 구조

  • api : 외부 통신에 대한 폴더.
  • model : 데이터 폴더.
  • util : 공통으로 사용되는 함수를 모아둔 폴더.
  • view : UI화면이 있는 폴더.
  • controller : 사용자로부터 입력 받아 Model을 업데이트 해주는 파일을 모아둔 폴더.


MVC 디자인 패턴 적용해보기

  1. pubspec.yaml 작성하기.
    mvc패턴을 사용하기 위해 아래 링크에서 mvc_pattern 패키지를 추가한다.
    https://pub.dev/packages/mvc_pattern/install
dependencies:
  flutter:
    sdk: flutter


  # The following adds the Cupertino Icons font to your application.
  # Use with the CupertinoIcons class for iOS style icons.
  cupertino_icons: ^1.0.2
  mvc_pattern: 8.12.0
  get: 4.6.5

  1. lib/model/number.dart 코드 작성하기.
    변수와 함수를 같이 작성한다.
class Number{
  int _num = 0;
  
  get num => _num;
  
  int increment() => ++_num;
  int decrement() => --_num;
}

  1. lib/controller/number_controller.dart 코드 작성하기.
    model에서 작성한 변수와 함수 가져다 사용한다.
    사용자의 업데이트가 있을 경우. setState 사용으로 화면을 다시 그려준다.
import 'package:mvc_pattern/mvc_pattern.dart';
import 'package:statement/mvc/model/number.dart';

class NumberController extends ControllerMVC {
  // 생성자 기본으로 작성해야 될 부분
  factory NumberController([StateMVC? state]) =>
      _this ??= NumberController._(state);

  // controller 생성자에 모델 생성자 초기화.
  NumberController._(StateMVC? state)
      : _number = Number(),
        super(state);

  final Number _number;
  static NumberController? _this;

  get num => _number.num;

  /// 화면 업데이트
  void update() => setState(() {});

  /// num 증가
  void incrementNum() {
    _number.increment();
    update();
  }
  
  /// num 감소
  void decrementNum(){
    _number.decrement();
    update();
  }
}

  1. lib/view/number_view.dart 코드 작성하기.
    Stateful안에 StateMVC를 확장하여 Controller를 전달한다.
import 'package:flutter/material.dart';
import 'package:mvc_pattern/mvc_pattern.dart';
import 'package:statement/mvc/controller/number_controller.dart';

class NumberView extends StatefulWidget {
  const NumberView({Key? key}) : super(key: key);

  
  State createState() => _NumberViewState();
}

class _NumberViewState extends StateMVC<NumberView> {
  _NumberViewState() : super(NumberController()) {
    numberController = controller as NumberController;
  }

  late NumberController numberController;

  
  Widget build(BuildContext context) {
    return Scaffold(
      body: SafeArea(
        child: Center(
          child: Column(
            mainAxisAlignment: MainAxisAlignment.center,
            children: [
              Text(numberController.num.toString()),
              ElevatedButton(
                  onPressed: () {
                    numberController.incrementNum();
                  },
                  child: const Text('증가')),
              ElevatedButton(
                  onPressed: () {
                    numberController.decrementNum();
                  },
                  child: const Text('감소')),
            ],
          ),
        ),
      ),
    );
  }
}

  1. main.dart 코드 작성하기.
void main() {
  runApp(const GetMaterialApp(
    title: 'Flutter Demo',
    home: NumberView(),
 ));
}

결과

증가 버튼을 클릭하면 0에서 클릭 수 만큼 값이 증가하고, 감소 버튼 클릭 시, 클릭 수 만큼 값이 감소한다.




참고 문서 :
https://pub.dev/packages/mvc_pattern
https://www.incodom.kr/flutter_mvc
https://minwook-shin.github.io/flutter-mvc/
https://www.youtube.com/watch?v=5xLXC1nnjlM&t=409s

profile
Flutter developer

0개의 댓글