(TIL) 6. React-Native : NativeBase (+ cleanArchitecture)

김동우·2021년 9월 8일
0

React-Native

목록 보기
6/17

1.

오늘은 정말 새로운 주제입니다.

RN을 사용하는 사람들에게 재밌는 lib 일 것 같습니다.

기존 RN의 StyleSheet와는 달리 인라인으로 style props를 작성할 수 있고, 다양한 기능들을 지원하고 있는 nativebase 입니다.

처음 봤을 때는 부트스트랩인가? 싶었는데, 비슷하긴 한 것 같습니다.

다만, 조금 더 유저의 노력이 들어갑니다.

그래도 디자인에 대한 부담을 줄일 수 있으니 관심있으신 분들은 사용해보시면 좋을 것 같습니다.

각종 토이 프로젝트에서 사용하기 좋은 느낌입니다.

2.

그래서 오늘은 nativebaserefactoring을 좀 해봤습니다.

여전히 좀 구리긴 합니다만, 그래도 나름의 스타일이 들어간 것 같아서 기분은 좋았습니다.

디자인 멈춰!

다양한 style hooks를 지원하고 있기에 버튼을 눌렀을 때 전체 배경색의 변경 등의 기능도 가능합니다.

다음 프로젝트는 아마도 nativebase를 애용하지 않을까 싶네요.

3.

지난주부터 계속 고민하던 바로 그 주제입니다.

Clean Architecture

해당 개념을 읽고, 공부했을 때는 분명 아~ 그런가보다 수준이었는데 막상 프로젝트에 적용하려니 각종 로직들을 수정하는 것은 물론 class와 추상에 대한 공부를 다시 하는게 맞지 않을까 생각이 들었습니다.

그래서 현재는 개념 학습을 위해 다양한 function 으로 내부가 이루어져 있는 구조입니다.

먼저, 글을 열심히 읽어본 결과, 현재 To Do List 의 경우 firebase를 사용하고 있기 때문에 data layer를 따로 고려하지 않아도 될 것 같다고 생각했습니다.

그러나 DB 접근 method class를 선언해두었기에 Repository 개념 정도는 가지고 갈 수 있었습니다.

useCase에 존재해야 하는 로직은 어떤 형태일지도 고민이 되었고, useCase 비즈니스 로직이 어떤 기능들을 수행하는지도 고민이 되었던 것 같습니다.

그리고 무엇보다도 ViewPresenter를 분리하는 일도 쉽지 않았습니다.

차근차근 해결해나간 결과, 나름의 기준을 정해보았습니다.

3.1

계층간섭이 가능한 개념은 계층 내에서 단 하나만 존재하기로 약속하자.

저는 위 글과 같이 presenter - useCase - repository 셋을 선택했습니다.

presenterrepository는 서로 접점이 없어 각 계층에서 어떤 일이 벌어지는지 알 수 없도록 구현했습니다.

: presenterrespository에 접근할 수 없고, 반대의 경우도 마찬가지라고 생각했습니다.

가장 고민이 되었던 것은 useCase입니다.

useCase의 경우 양방향으로 소통할 수 있는 구조인 것으로 보이는데, 현실적으로는 repository에서 받아온 DB method를 생성해서 실제 로직에 사용하는 식으로 구현되었습니다.

3.2

약속된 기능만을 수행할 수 있도록 작성하자.

useCase에서는 repository의 DB method를 내부에 생성했기 때문에 DB 접근이 가능합니다.

그러나 presenter는 DB에 접근하는 로직을 내부에 보유하지 않아 접근할 수 없습니다.

presenter의 경우 해당 프로젝트에서는 handle~ 등과 같은 View control이 가능합니다.

그러나 DB에 접근하기 위해서는 View에 특정 메소드를 호출해야 합니다.

분명 View와 useCase는 접점이 존재하지 않는데, 어떻게 작성해야 할지 고민이 많았던 것 같습니다.

signIn 기능이 대표적인 예시인데,

signIn의 presenter를 제 멋대로 작성해본 것을 코드로 올려보겠습니다.

import auth from '@react-native-firebase/auth';
import {checkUserInfoInDB} from '../../../domain/SignIn/usecase/authLogic';

...

export const signInCheck = (signInInfo: any): void => {
  const userId = auth().currentUser?.uid;

  checkUserInfoInDB(`users/${userId}/user`, signInInfo);
};

극단적이긴 한데, signInCheck() 이라는 하나의 함수를 정의해두고, 내부에서 userInfo가 DB에 존재하는지 확인하는 함수를 호출합니다.

presenter에서는 약속대로 DB에 접근하지 않지만, 현재 로그인한 유저가 맞는지 auth 메소드를 통해 점검하고 있습니다.

명확하게 분리하기 위해서는 사실 useCaseauth()가 존재해야 하는데, 해당 부분을 어떻게 옮기는게 맞을지도 지속적으로 고민하고 있습니다.

극히 작은 규모의 프로젝트에서 어거지로 presenteruseCase를 분리하려다 보니 이런 고민이 생기는 것 같습니다.

앞으로는 cleanArchitecture 이전에, class로 어떻게 계층 내부에서 인터페이스화했는지를 더 공부해야 할 것 같습니다.

그래서 요즘은 java 코드를 더 많이 보게 되는 것 같습니다.

3.3

해당 개념에 대해 조악하게나마 적용해보니 유일하게 느낀 점이 있었습니다.

유지보수에 무조건 유리할 수 밖에 없겠다! 하는 점입니다.

어떤 부분이 문제가 생기면 어딜 참고하면 되는지 바로 알 수 있고,

예를 들면 DB에서 유저정보를 불러오지 못하는 것 같아요!
=> presenter 내 경로, useCase 내 DB 로직 점검

그러나 아직도 두 계층을 확인해야 한다는 점에서 제 계층분리가 잘못되었다는 것을 알 수 있는 것 같습니다.

하나로 줄일 수 있는 방법을 늘 고민하는데, 아직은 쉽지 않은 것 같습니다....

또한 로직의 길이가 짧아지고, KISS 원칙을 잘 지킬 수 있게 되는 것 같았습니다.

하나의 함수 내부 로직을 고민하고, 또 고민하기 때문입니다.

그렇기에 좋은 도전이었다고 생각합니다.

4.

주절주절 참 많이도 썼는데, 사실 잘 몰라서 그렇습니다.

시행착오를 수도 없이 겪었는데, 머리 속에서 수도 없이 고민했기에 글로 적는 것이 마냥 쉽지가 않네요.

그럼에도 더 무언가를 공부하고, 도전하는 기분이 들어 좋았던 것 같습니다.

해당 주제를 다시 가지고 온다면 그 때는 누구에게나 자랑하듯 보여줄만한 코드들과 함께 왔으면 좋겠습니다.

그러기 위해 더 열심히 살아야겠네요.

그럼 이번 글은 여기서 마치겠습니다. 읽어주셔서 감사합니다.

0개의 댓글