Flutter는 다양한 디자인 패턴을 사용하여 애플리케이션 개발을 더욱 구조적이고 유지보수가 쉽게 만들 수 있습니다. 주요 패턴들을 정리해보겠습니다.
1. Provider 패턴
• 설명: Flutter 애플리케이션에서 상태 관리를 간단하고 효율적으로 수행하기 위해 사용됩니다. InheritedWidget을 기반으로 하여, 상위 위젯 트리에서 상태를 하위 위젯 트리에 전달할 수 있습니다.
• 사용법: provider 패키지를 사용하여 구현합니다.
• 예제:
class Counter with ChangeNotifier {
int _count = 0;
int get count => _count;
void increment() {
_count++;
notifyListeners();
}
}
void main() {
runApp(
ChangeNotifierProvider(
create: (context) => Counter(),
child: MyApp(),
),
);
}
class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
return MaterialApp(
home: Scaffold(
appBar: AppBar(title: Text('Provider Example')),
body: Center(
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
Text(
'You have pushed the button this many times:',
),
Consumer<Counter>(
builder: (context, counter, _) {
return Text(
'${counter.count}',
style: Theme.of(context).textTheme.headline4,
);
},
),
],
),
),
floatingActionButton: FloatingActionButton(
onPressed: () {
Provider.of<Counter>(context, listen: false).increment();
},
tooltip: 'Increment',
child: Icon(Icons.add),
),
),
);
}
}
2. BLoC (Business Logic Component) 패턴
• 설명: BLoC 패턴은 비즈니스 로직을 UI에서 분리하여 유지보수성과 테스트 용이성을 높입니다. 이벤트와 상태 스트림을 사용하여 비동기 데이터 흐름을 관리합니다.
• 사용법: flutter_bloc 패키지를 사용하여 구현합니다.
• 예제:
class CounterEvent {}
class CounterState {
final int counter;
CounterState(this.counter);
}
class CounterBloc extends Bloc<CounterEvent, CounterState> {
CounterBloc() : super(CounterState(0));
@override
Stream<CounterState> mapEventToState(CounterEvent event) async* {
if (event is IncrementEvent) {
yield CounterState(state.counter + 1);
}
}
}
void main() {
runApp(MyApp());
}
class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
return MaterialApp(
home: BlocProvider(
create: (context) => CounterBloc(),
child: MyHomePage(),
),
);
}
}
class MyHomePage extends StatelessWidget {
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(title: Text('BLoC Example')),
body: Center(
child: BlocBuilder<CounterBloc, CounterState>(
builder: (context, state) {
return Text(
'${state.counter}',
style: Theme.of(context).textTheme.headline4,
);
},
),
),
floatingActionButton: FloatingActionButton(
onPressed: () {
BlocProvider.of<CounterBloc>(context).add(IncrementEvent());
},
tooltip: 'Increment',
child: Icon(Icons.add),
),
);
}
}
3. Redux 패턴
• 설명: 상태 관리 라이브러리로, 애플리케이션의 상태를 하나의 중앙 저장소에서 관리합니다. 액션을 통해 상태를 업데이트하고 리듀서를 통해 새로운 상태를 반환합니다.
• 사용법: flutter_redux 패키지를 사용하여 구현합니다.
• 예제:
// State
class AppState {
final int counter;
AppState(this.counter);
}
// Actions
class IncrementAction {}
// Reducer
AppState counterReducer(AppState state, action) {
if (action is IncrementAction) {
return AppState(state.counter + 1);
}
return state;
}
// Store
final store = Store<AppState>(
counterReducer,
initialState: AppState(0),
);
void main() {
runApp(MyApp());
}
class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
return StoreProvider<AppState>(
store: store,
child: MaterialApp(
home: MyHomePage(),
),
);
}
}
class MyHomePage extends StatelessWidget {
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(title: Text('Redux Example')),
body: Center(
child: StoreConnector<AppState, String>(
converter: (store) => store.state.counter.toString(),
builder: (context, counter) {
return Text(
counter,
style: Theme.of(context).textTheme.headline4,
);
},
),
),
floatingActionButton: FloatingActionButton(
onPressed: () {
StoreProvider.of<AppState>(context).dispatch(IncrementAction());
},
tooltip: 'Increment',
child: Icon(Icons.add),
),
);
}
}
4. MVVM (Model-View-ViewModel) 패턴
• 설명: 애플리케이션의 UI를 모델과 분리하여 유지보수성과 테스트 용이성을 높입니다. ViewModel은 모델 데이터를 처리하고 이를 뷰에 바인딩합니다.
• 사용법: provider와 ChangeNotifier를 사용하여 구현합니다.
• 예제:
class CounterViewModel extends ChangeNotifier {
int _counter = 0;
int get counter => _counter;
void increment() {
_counter++;
notifyListeners();
}
}
void main() {
runApp(MyApp());
}
class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
return ChangeNotifierProvider(
create: (context) => CounterViewModel(),
child: MaterialApp(
home: MyHomePage(),
),
);
}
}
class MyHomePage extends StatelessWidget {
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(title: Text('MVVM Example')),
body: Center(
child: Consumer<CounterViewModel>(
builder: (context, viewModel, _) {
return Text(
'${viewModel.counter}',
style: Theme.of(context).textTheme.headline4,
);
},
),
),
floatingActionButton: FloatingActionButton(
onPressed: () {
Provider.of<CounterViewModel>(context, listen: false).increment();
},
tooltip: 'Increment',
child: Icon(Icons.add),
),
);
}
}
참고 자료
• Flutter Documentation - Provider
'프론트엔드 > Flutter' 카테고리의 다른 글
flutter future 키워드 및 aysnc await 를 통한 비동기처리 (0) | 2024.07.28 |
---|---|
flutter firestore 시작하기 - firebase 데이터베이스 (0) | 2024.07.25 |
flutter SQLite 데이터베이스 저장 (1) | 2024.07.25 |
flutter에서 바텀 네비게이션 바(Bottom Navigation Bar) (0) | 2024.07.24 |
flutter 주요 버튼 위젯 모음 (1) | 2024.07.24 |