Flutter - provider패턴 아키텍처에 대한 이해
ㅇprovider 패턴의 목적은 bloc패턴과 같습니다. Business Logic과 UI를 떨어 뜨려 놓고 필요에 따라 원하는 부분만 업데이트를 할 수 있습니다.
📕 Provider 패턴이란??
・ Provider는 플러터 커뮤니티에서 만든 플러그인이었으나 현재는 구글에서 추천할 정도로 편리합니다. 원래 구글은 Provider가 아닌 Bloc 패턴 사용을 권장했었다고 합니다. 이유는 플러터는 UI와 Design 모두 소스코드로 관리되지 않으면 한 클래스에 여러 코드가 몰리는 문제점이 있었습니다. 그래서 이를 해결하기 위해 UI와 데이터 처리 로직을 분리하기 위해 Bloc 패턴을 제공하게 됐습니다. 하지만 Bloc패턴은 사용하기 어렵다는 단점이 있었고 단순한 로직을 구성하려해도 최소 4개의 클래스를 만들어야 했습니다.
- 실 습 -
라이브러리
아래 링크에 들어가 installing에 Provider 패키지 코드를 복사하여 pubspec.yaml 파일에 추가하여 다운로드,
provider | Flutter Package
A wrapper around InheritedWidget to make them easier to use and more reusable.
pub.dev
dependencies:
provider: ^6.0.2
코드의 이해를 돕기 위해 폴더의 위치를 다음과 같이 구성,
Bloc패턴 과같이 Provider를 이용해 Count를 보여주는 앱을 구현,
구현 포인트
- UI 분리
- Provider 분리
- Consumer
- UI 분리 / Consumer
- countHomeWidget.dart
class CountHomeWidget extends StatelessWidget {
late CountProvider _countProvider;
@override
Widget build(BuildContext context) {
_countProvider = Provider.of<CountProvider>(context);
// Consumer를 사용해서 이부분만 업데이트 한다.
return Center(
child: Consumer<CountProvider>(
builder: (context, provider, child) {
return Text(
provider.count.toString(),
style: TextStyle(fontSize: 80),
);
}
)
);
}
}
구현 포인트는 late CountProvider, late keyword
non-nullable 로 변수가 선언되면 선언과 동시에 초기값을 주어야 한다. 그런데 어떤 경우에는 변수가 non-nullable 로 선언되기는 하지만 선언과 동시에 초기값을 줄수 없는 경우도 있다. 즉 변수가 null 인 상태로 이용되지는 않지만 초기값이 앱이 실행되면서 결정되는 경우이다. 이때 late keyword 를 사용하면 된다. late 는 단어 뜻 그대로 초기화 시점을 뒤로 미루겠다는 의미이다. Flutter 2.0에서는 이렇게 사용해야 Nullable한 변수 사용 가능하다.
여기서 Consumer를 사용하여 Provider를 불러 왔는데 Consumer Builder에는 3가지 가 필요하다. context, provider, childe
여기서 우리가 사용할 것은 provder, provider.count.toString()을 이용해 Provder에 있는 Count값 가져와 준다.
Consumer를 사용하는 경우는 builder 부분만 호출되기 때문에 현 위젯이 리로드 되지 않는다. 즉, 여러 효과나 연산이 많이 있는 위젯일 경우는 Consumer를 사용하는 것이 좋을 것으로 보인다.
- countHomeWidget.dart
// 상태관리를 하는 변수
class CountProvider extends ChangeNotifier{
int _count = 0;
int get count => _count; // 외부에서 접근 가능
add(){
_count += 1;
notifyListeners();
}
remove(){
_count -= 1;
notifyListeners(); // 상태값 업데이트
}
}
상태 관리를 하기 위한 provider에는 private로 설정된 _count와 외부에서 접근 가능하도록 하는 get count가 있다. 여기서 add() 와 remove()함수를 통해 count의 값을 조절 한다.
- Home.dart
class Home extends StatelessWidget {
late CountProvider _countProvider;
@override
Widget build(BuildContext context) {
_countProvider = Provider.of<CountProvider>(context, listen: false);
return Scaffold(
appBar: AppBar(
title: Text("Provder Pattern"),
),
body: CountHomeWidget(),
floatingActionButton: Row(
mainAxisAlignment: MainAxisAlignment.end,
children: [
IconButton(onPressed: () {
_countProvider.add();
}, icon: Icon(Icons.add)),
IconButton(onPressed: () {
_countProvider.remove();
}, icon: Icon(Icons.remove)),
],
),
);
}
}
초기 Home 설정을 하고 Click시 Provder에 있는 값을 불러오는 것 을 목표로 하고 완성시켰다. 여기서의 핵심은
Provider를 호출해 접근, listen: false를 통해 구독된 모든 위젯들에게 알림을 보내지 않게 한다!!
구현 완료
final )
구현을 했었던 Provider 중 MultiProvider를 통해 여러개의 Provider 관리 또한 할 수 있다. 여러 아키텍처 중 provider 패턴은 비지니스 로직과 UI를 구분하기 가장 쉽고 간편해서 Flutter가 더욱더 매력이 있는 것 같다.