Bloc은 Business Logic Component의 약자로 UI와 Business Logic을 분리하기 위한 디자인 패턴입니다.
rxdart 패키지를 사용하여 간소 구현합니다.
Bloc 패턴은 UI와 비지니스 로직을 분리하여 코드를 효율적으로 관리할 수 있도록 하는 디자인 패턴입니다.
한 화면상에 많은 위젯이 포함되어 있다면 화면을 새로고침 할 때 마다 불필요한 위젯까지 함께 새로고침 되어 부하를 발생시킬 수 있습니다.
Bloc 패턴에서는 각 Bloc마다 대응되는 하위 UI요소가 있으며 값의 변경을 인지하여 값의 변경을 확인하고 필요한 UI요소만을 업데이트 합니다.
또한 비지니스 로직이 분리되었기 때문에 기능만을 따로 테스트할 수 있습니다.
Bloc 디자인 패턴을 사용하기 위해서는 값의 변경을 인지할 수 있어야 합니다.
rxdart패키지를 사용하여 변경을 인지하고 bloc 디자인 패턴을 구현합니다.
import ...
class TestBloc {
var initTest = '/// init';
//bloc singleton
//static final TestBloc _instance = TestBloc._internal();
final _testSubject = BehaviorSubject();
Stream get test => _testSubject.stream;
TestBloc() {
_testSubject.sink.add(initTest);
}
dynamic fetchData() async {
await Future.delayed(const Duration(milliseconds: 1000), () {});
return '/// click';
}
void click() async {
var test = await fetchData();
_testSubject.sink.add(test);
}
void dispose() {
_testSubject.close();
}
}
import ...
class TestView extends StatelessWidget {
TestView({Key? key}) : super(key: key);
Widget build(BuildContext context) {
return Column(
children: [
TextButton(
onPressed: () {
//bloc 비지니스 로직 호출
//해당 bloc이 생성된 곳의 변수를 불러옵니다.
testBloc.click();
},
child: const Text(
'Click',
),
),
Container(
child: StreamBuilder(
stream: testBloc.testResult,
initialData: 'start',
builder: (BuildContext context, AsyncSnapshot snapshot) {
if(snapshot.hasData) {
return Text(snapshot.data.toString());
}
return Container();
}
),
),
],
);
}
}
import ...
//bloc
late TestBloc testBloc;
class TestPage extends StatefulWidget {
TestPage() {}
State<TestPage> createState() => _MainPageState();
}
class _MainPageState extends State<TestPage> {
void initState() {
super.initState();
//bloc 생성
testBloc = TestBloc();
}
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text('Bloc'),
),
//bloc과 대응되는 UI Component
body: TestView(),
);
}
}