programming코딩

리얼 Flutter #5 App 만들기 – BLOC

BLOC 는 앞으로 제가 Flutter로 App을 만드는데 가장 중요한 부분입니다.

설명과 함께 구현하는 코드는 github repository에 있고 본 글은 commit 0126e41기준입니다.

혹시 공부를 함께 하시는 분은 github에서 project를 fork하셔도 되고 watch하시면 제가 방향을 잡는데 도움이 될것 같습니다. Star도 해주시면 감사하구요.

Why BLOC

BLOC (Business Logic Component)는 UI와 Business logic을 분리시켜주어 생산성과 재사용성을 높혀주는 Architecture입니다.

MVVM, Redux 등 Presentation과 Business Logic을 분리하는 다양한 Architecture들이 있습니다.

직접 만들어도 되지만 Framework별로 Library가 구비되어 있고 예제가 많은 것을 사용하는게 효율성이 높습니다.

Flutter에 있어 BLOC가 그러한 Architecture중에 하나입니다.

그래서 저는 BLOC를 사용합니다.

BLOC Architecture

BLOC architecture

BLOC는 Software 구조를 UI, BLOC 그리고 DATA로 역할을 나누는 Architecture입니다.

역할은 단어 그대로 UI, Business Logic, Data 역할로 나누는 것입니다.

그리고 다음은 각 역할간에 Interface들입니다.

  • states : BLOC의 State를 UI에 전달하면 UI는 여기에 맞게 UI를 구성합니다.
  • events : UI로부터 Interaction에 의한 Event를 BLOC에 전달합니다.
  • request and response : BLOC는 Data를 handling합니다. request와 response가 있다는 것은 async (비동기) 적인 구조를 포함함을 의미합니다.

flutter_bloc import 하기

flutter로 App을 만드는 우리는 bloc말고 flutter_bloc 를 import합니다.

flutter_bloc의 install 정보 페이지 가서 앞서 Chapter #4 pubget for packages에서 설명한대로 pubspec.yaml에 추가하고 pub get 해줍니다.

flutter BLOC library dependency

idea note 예제 코드와 파일 구성

지난 Chapter #3 Routes에서 폴더와 UI 파일들을 구성했었습니다.

코드는 앞서 이야기한 github repository에 있습니다.

BLOC를 구현하기 위해 bloc와 model 폴더에 빨간색으로 표시한 파일들을 추가했습니다.

IdeaBloc

bloc는 data와 연결되고 event를 처리하여 state를 관리하는 역할을 합니다.

BLOC 예제

중요한 부분들을 빨간색으로 표시하고 숫자를 적었습니다.

그리고 다음은 그 숫자에 대한 각 설명입니다.

  1. Bloc를 상속 받습니다. 이 때 Bloc에 적용할 Event, State type을 정의합니다. 예제에서 사용한 IdeaEvent와 IdeaState는 아래에 설명됩니다.
  2. Event를 처리해주기 위해서 구현해야하는 Bloc의 abstract method입니다.
  3. if(event is IdeaEventFetching) event가 IdeaEventFetching인 경우임을 알 수 있습니다. 즉, IdeaEventFetching이 class이겠죠.
  4. Data Fetching 처리를 하고 나면 상태를 update합니다. yield 를 통해 Stream에 state를 출력해줍니다. 그래서 mapEventToState의 type이 Stream이어야 합니다.
  5. Bloc는 model를 ineterfacing하므로 repository를 갖도록 했습니다.
  6. event가 IdeaEventFetching일때 ideaRepository가 data를 가져오도록 합니다.
  7. data는 network으로부터 가져올 수도 있고 시간이 걸리게 되는데 이를 기다린후에 다음을 처리해야 하므로 await를 하게 합니다.
  8. 그리고 stream을 위해 yield를 사용할 경우 async*를 붙여야 합니다.

IdeaState

다음은 State 코드에 대한 설명입니다.

  1. abstract 로 IdeaState를 정의합니다.
  2. 그리고 각 State는 IdeaState를 상속받습니다. 저는 Idea note의 초기화가 되기전과 초기화가 끝난 state로 구분하여 정의하였습니다.
  3. 그럼 bloc가 막 생성될 때는 초기화가 되기 전이겠죠? 그러므로 IdeaStateNotInitialized() 를 initial state로 정의합니다.

IdeaEvent

다음은 Event에 대한 설명입니다.

이번 Chapter는 BLOC 부분이므로 Event를 처리하는 부분만 있습니다.

Event를 호출하는 부분은 UI쪽에 있사오니 다다음 Chapter에서 설명하도록 하겠습니다.

  1. Event도 abstract로 정의합니다.
  2. 그리고 각 Event들은 IdeaEvent를 상속 받습니다.
  3. Event도 추상화를 할 수 있습니다. 그 event가 처리되어야 하는 idea를 포함하도록 하였습니다.
  4. Fetching의 경우 특정 idea와 상관이 없으니 null로 처리하고 Saving의 경우에는 특정 idea를 저장하는 경우애 사용되니 추가하도록 하였습니다.
  5. mapEventToState에서 event를 처리할때 해당 attribute를 사용하면 됩니다.

마치며

bloc를 구현한 과정을 설명을 해봤습니다.

다음 Chapter에서 Model과 UI에 적용하는 것을 진행하게 되는데 Bloc를 사용해야지 반응형 UI를 구현하는데 큰 도움이 되는 것을 알 수 있습니다.

그리고 중간에 Stream, Future, final등 dart의 많은 특이한 컨셉들은 차차 알아보도록 하겠습니다.

Leave a Reply