반응형
flutter_provider

Flutter Provider 패턴이란?

  • Provider란? 데이터 생산과 소비
  • Provider 써보기
  • ChangeNotifierProvider로 변하는 데이터 다뤄보기
  • MultiProvider로 여러 프로바이더 관리하기

 

Provider가 주목받게된 배경

 

Provider 는 올해 Google IO (2019 Google IO) 에서 추천되면서 큰 주목을 받았습니다.

원래 커뮤니티에서 만든 플러그인인데 구글에서 공식으로 추천을 한 거죠.

 

작년 구글 IO 떄 구글은 Bloc 패턴을 사용하길 권했습니다.

Bloc 패턴은 UI와 데이터 처리 로직(비즈니스 로직)을 분리하는 방식입니다.

 

플러터는 UI도 코드다 보니, 잘 관리 안 해주면

코드가 한 클래스에 너무 많이 몰리는 문제가 있었습니다.

 

이를 해결하기 위해 나온 게 Bloc 패턴입니다.

그런데 BLoc 패턴은 사용하기 너무 어렵다는 사람이 많았습니다.

단순한 로직을 짜려고 해도 4개 정도는 클래스를 만들어야 했죠.

 

반면 Provider 패턴을 쓰면 데이터 공유나 로직의 분리를 좀 더 간단히 할 수 있습니다.

 

프로바이더 패턴을 쓰는 이유는?

 

a. 관심사의 분리 (separation of concerns)

관심사의 분리는 디자인 원칙의 하나입니다.

보통 관심사는 어떤 코드가 하는 일을 말합니다.

UI를 담당하는 코드, 네트워크를 담당하는 코드, 데이터를 담당하는 코드 등

코드를 역할에 따라 나눌 수 있죠.

 

보통은 한 클래스가 여러 역할을 할 수록, 클래스가 커지고 관리가 어렵게 됩니다.

따라서 클래스가 하나의 역할(관심)만 갖도록, 클래스를 나누죠.

 

이게 바로 관심사의 분리입니다.

 

Provider나 Bloc 패턴을 쓰는 이유는 관심사의 분리를 위해서에요.

 

b. 데이터의 공유

하나의 데이터를 여러 페이지에서 공유하고 싶을 때가 있습니다. 유저 인증 정보의 경우 장바구니, 회원 등급 등 여러 페이지에서 쓰이죠. 근데 페이지마다 인증 정보를 새로 불러온다면 앱이 복잡해지고, 비용도 많이 들겠죠?

 

이럴 때 데이터 공유가 필요합니다.

Provider 패턴을 쓰면 데이터 공유를 쉽게 할 수 있습니다.

 

c. 좀 더 간결한 코드

Bloc 패턴의 경우 클래스들을 역할 별로 나누는 데는 좋지만

코드 자체가 복잡해지는 경향이 있습니다.

 

Provider 패턴을 쓰면 좀 더 적은 코드로

클래스들을 구분해서 쓸 수 있죠.

 

구글에서도 중규모 프로젝트는 Provider 패턴을, 대규모 프로젝트는 Bloc 패턴을 추천하고 있습니다.


1. 프로바이더의 구조 - 데이터 생산과 소비

 

Provider는 데이터를 생산하고, 소비하는 2부분으로 되어 있습니다.

어떤 데이터를 생산하느냐에 따라 Provider의 종류가 달라지죠.

그냥 Provider가 되기도 하고 StreamProvider가 되기도 하고 합니다.

 

Provider가 어떻게 데이터를 생산하고 소비하는 지 알아보고, 실제 앱에서 활용해 보도록 하겠습니다.

 

일단 라이브러리부터 추가해주세요.

pubspec.yaml

 

 

1.1 Provider 데이터 생산하기

 

데이터를 생산할 때는 꼭 데이터 타입을 적어줍니다.

여기선 int 형태로 데이터를 만들었죠.

 

1.2 Provider 데이터 소비하기

 

Provider에서 만든(제공하는) 데이터를 쓰려면

Provider.of(context)Consumer() 위젯을 사용합니다.

 

저는 Provider.of(context) 가 더 쓰기 편해 이쪽을 더 선호합니다.

그럼 간단히 앱을 만들어볼께요.

 

요런 디자인입니다 :)

flutter_01

예제 1.1 - 기본 Provider 사용해보기 : 데이터 생산

 

 

Provider를 쓰려면 부모 위젯을 Provider로 감싸줘야합니다.

전체 앱에서 사용하고 싶으면 MateriapApp을 감싸면 됩니다.

 

Provider에서 어떤 값을 쓸지를 정해야 하는데요.

전 5를 주었습니다. 지금은 value가 5로 고정되어 있지만, 변하는 값을 넣는 것도 얼마든지 가능합니다.

 

이제 Provider가 제공한 데이터를 사용해보겠습니다.

 

예제 1.2 - 간단히 Provider 사용해보기 : 데이터 소비

 

Provider.of(context) 함수를 통해

데이터를 가져옵니다.

 

이 값은 5 입니다. 부모 위젯에서 정한 값이죠.

데이터를 만드는 곳과 쓰는 곳이 분리되어 있습니다.

 

이게 Provider 패턴의 가장 큰 특징이죠.

사실상 옵저버 패턴과 큰 차이가 없어요.

 

그럼 Provider를 써서

값이 변할 때 어떻게 하는지를 알아보겠습니다.

 

2. ChangeNotifierProvider 사용하기 - 변하는 값 처리하기

 

UI에 있는 값이 변했을 때, UI를 변경해 줘야합니다.

이를 setState() 로 할 수도 있겠지만

ChangeNotifier 를 쓰면 같은 일을 할 수 있습니다.

 

ChangeNotifier를 믹스인 (mixin) 한 클래스는

notifyListeners() 함수를 부를 수 있습니다.

이 함수를 쓰면 UI가 업데이트 됩니다.

 

예제 2.1은 counter 값이 변할때, UI를 업데이트 하도록 만든 클래스입니다.

 

예제 2.1 - Counter 클래스

 

Counter 클래스를 Provider에 넣어볼텐데요.

 

Counter 클래스가 ChangeNotifier를 믹스인 했기에

ChangeNotifierProvider 를 사용해줘야합니다.

 

예제 2.2 - CounterApp.
ChangeNotifierProvider 로 위젯을 감싸줍니다 - 데이터 사용할 준비하기

 

머터리얼 앱을 ChangeNotifierProvider로 감싸고 있습니다.

builder 속성에서 초기값을 정하고 이를

자식 위젯들에서 사용합니다.

 

예제 2.3 ChangeNotifierProvider의 값 사용하기

예제 2.2에서 제공하는 데이터를 위젯에서 보여줍니다.

+,- 버튼을 누를 때마다 값이 바뀌죠.

 

 

아래 그림 같은 UI 인데요.

+, - 버튼을 누르면 중앙에 있는 값이 바뀝니다.

flutter_02

 

 

 

그럼 다른 페이지에서도 Counter 값이 잘 공유되는지 알아볼께요.

 

예제 2.4 - FirstPage 다른 페이지에서도 값이 동일한지 확인

 

flutter_03

 

다른 페이지에서도 값이 동일합니다.

똑같이 5가 나오는 걸 알 수 있죠.

 

생각보다 프로바이더 쓰는 건 간단합니다!!

다만 문제가 하나 있는데요.

 

Provider가 여러개 일수록 관리가 어려워진다는 거죠.

게다가 Provider 가 중첩될 경우엔 앱이 난잡해지기 쉽습니다.

 

이때 쓰는 게 MultiProvider 에요.

 

3. MultiProvider - 여러 프로바이더 같이 사용하기

 

멀티 프로바이더를 쓰면 프로바이더 관리가 상당히 편해집니다.

다른 위젯들이랑 섞일 일이 없어서 쓰기 편해지죠.

사용법은 간단합니다.

 

MultiProvider의 providers 속성에 원하는 프로바이더를 적어주면 됩니다.

여러개 적을 수 있죠.

 

MultiProvider 사용 예

 

프로바이더는 자료형으로 어떤 값을 가져올지 구분합니다.

근데 멀티 프로바이더에 같은 자료형이 여러번 정의 된다면 어떻게 될까요?

 

MultiProvider - 같은 자료형이 여러개면 가장 밑에 있는 것에 접근.

 

같은 자료형인 프로바이더가 여러개일 경우, 가장 밑에 값으로 처리합니다.

 

그럼 좀 더 실용적인 예제를 만들어보겠습니다.

파이어 스토어의 데이터를 받아서 보여주는 예제에요.

 

화면 2개로 구성되어 있는데 1개는 로그인 화면, 1개는 유저 데이터를 보여주는 화면입니다.

 

예제3. 로그인 화면 - 로그인 안 되었을 때 나옴

flutter_05

 

예제3. 유저 데이터 화면 - 로그인 되면 나옴

flutter_04

 

 

 

 

우선 라이브러리부터 추가하겠습니다.

예제 3.1 pubspec.yaml

 

 

이제 파이어 스토어에서 필요한 데이터를 만들어주세요.

데이터는 아래 그림과 같은 형식입니다.

User 콜렉션과 다큐먼트를 만들어 주세요~!

 

예제 3.2 파이어스토어에 데이터 추가하기

flutter_firestore

 

파이어 스토어의 데이터를 앱에서 읽으려면

그에 걸맞은 클래스가 필요하겠죠?

user.dart 에서 이 일을 합니다.

 

예제 3.3 user.dart - 데이터를 담을 클래스

 

 

데이터 관리는 따로 클래스를 만들어서 하겠습니다.

Database Provider 라는 클래스인데요.

파이어 스토어로부터 데이터를 읽어 들입니다.

 

예제 3.4 database_provider.dart - 파이어 스토어를 관리할 클래스

 

이제 프로바이더를 써서 데이터를 읽어들이도록 할께요.

DatabaseProvider 클래스에서 만든 함수 2개를 사용합니다.

 

 

예제 3.5 login_app.dart - 로그인 화면을 처리하고, 유저 데이터를 보여줄 클래스

 

로그인이 되었으면 유저 데이터를 보여주고,

로그인이 안 되었으면 email, password 입력 화면이 나옵니다~!

Provider(프로바이더)를 쓰면 이런 상태 관리를 정말 쉽게 할 수 있죠.

 

전 편의상 유저 데이터를 보여주는 위젯은 따로 클래스로 뺐습니다.

이 부분까지만 하면 이 예제는 끝이에요.

 

예제 3.6 user_list.dart - 유저 데이터를 보여줄 위젯

 

 

 

 

이제까지 Provider 에 대해서 알아보았습니다.

Bloc 패턴에 비하면 정말 간결합니다.

Provider 패턴을 쓰면 좀 더 부담없이 깔끔한 코드를 작성할 수 있단 생각이 드네요!

 

이 글에 쓰인 소스는 여기 에서 찾아보실 수 있습니다.

 

예제 1,2,3은 주석 처리를 지우면서 실행해 보세요!

 

이번 글에선 프로바이더에 대해서 알아보았는데요.

다음 글에선 애니메이션이나 파이어베이스에 대해서 알아볼 예정입니다.

 

여기까지 읽어주셔서 감사합니다.


 

참고한 자료들

멀티 프로바이더 부분 참고 - 유튜브 Fireship 채널 영상 ( https://www.youtube.com/watch?v=vFxk_KJCqgk )

프로바이더 아키텍처 - https://medium.com/flutter-community/flutter-architecture-provider-implementation-guide-d33133a9a4e8

 

반응형

+ Recent posts