Flutter를 처음 공부하면 대부분의 입문자는 Flutter의 Widget을 접하고 이를 이용하여 간단한 UI를 제작합니다. 학습과정에서 제작하는 UI는 단순하고 간단합니다.
하지만, 실제로 디자이너들을 포함한 협업 프로젝트를 진행하다보면 Flutter의 Widget을 디자인 요구사항에 맞게 수정해서 사용하는 것이 대부분입니다.
또한, 앱의 구조가 복잡하면 복잡할수록 수없이 많은 화면들이 존재하고 커스텀 Widget을 조합한 구조가 됩니다. 어떤 화면에서는 다른 화면의 Widget을 공통으로 갖고 있고, 나아가서 Widget들을 조합한 큰 범주의 Widget을 가질수도 있습니다.
이렇다보니 실제로 작업 중 다양한 파일을 다니며 어디에 어떤 파일이 있는지조차 파악하기 힘들 수 있는데요. 오늘은 Flutter에서의 UI 설계 전략과 View, Widget, Component의 개념에 대해서 알아보겠습니다.
Flutter docs에서는 모든 것은 Widget이라고 하죠. 맞습니다. Flutter에서 Widget은 UI를 구성하는 기본 단위입니다. 여러 Widget이 다양한 제약조건과 정렬을 이룬채로 흔히 화면이 만들어집니다. 화면 역시도 Widget입니다.다만, 프로젝트에서는 이러한 Widget을 구분할 필요가 있습니다. 단순하게 모든 것은 Widget이기 때문에 Widget으로 분류하게 된다면 우리의 프로젝트의 UI 계층은 너무나 많은 파일이 얽혀서 유지보수가 힘들게 합니다. 또한, 재사용 가능한 위젯인지 아닌지 구분하기도 힘들죠.
소개에서 설명했듯이 앱의 디자인 요구사항에 따라 다양한 커스텀 Widget을 제작하게 될 것입니다. 또한, 이 Widget들과 기본 Widget을 조합하는 등의 행위로 화면을 제작할 수 있습니다. 또는 다른 화면 제작에서도 이전에 제작한 Widget을 사용할 경우가 등장할 수 있겠죠.
당연히 다른 화면에서 동일한 Widget을 사용해야하는 경우 분리하여 관리하는게 최고지 않겠습니까??
이를 위해서 명확한 기준을 세우고 Widget을 구분하여 불필요한 코드를 줄이고 재사용성을 높여야 합니다.
Text, Container, Row, Column 등등 Flutter에서는 해당 Widget을 소개하며 Component라고 소개합니다. 이 Widget들은 재사용이 가능하여 조합과 정렬을 통해 커스텀 Widget을 만들 수 있게 도와줍니다. 또한, property를 바꿔주면 외형도 바꿀 수 있습니다.
Component는 이러한 Widget의 조합을 통해 재사용이 가능한 Widget 조합을 분리하는 행위입니다. UI 측면에서 Component를 이해해봅시다.
여기 인스타그램의 UI입니다. 전체적으로 개별적인 화면이지만 공통적인 부분이 몇몇 보입니다.
예를 들어, 사용자의 이미지 아바타는 크기는 달라도 여러곳에서 사용되고 있습니다.이러한 Widget을 분리하여 Component화한다면 코드의 중복을 방지하고 재사용을 높일 수 있으며 유지보수 측면에서도 굉장히 긍정적일 것 같지 않나요??
다만, 이런 Component는 여러곳에서 사용될 수 있기에 의존성이 존재해서는 안됩니다. 이 점을 유의하여 Component를 만들어봅시다.
Flutter docs에서 View는 Screen일 수 있지만, 실제로는 앱 전체에서 재사용되어야 하는 기능을 캡슐화한 단일 UI일 수도 있다고 합니다.
로그아웃 버튼이 존재하고, 이 버튼은 사용자의 편의성을 위해서 여러 화면에서 제공될 수 있습니다. 로그아웃 기능을 수행하기 위하여 ViewModel의 의존성을 가질 수 있죠.
그렇다면 의문이 들 수 있습니다.
"아니 그러면 화면이 아닌 View는 Component랑 구분이 좀 모호하지 않나요?? ㅋㅋㄹㅃㅃ"
"하지만 View는 ViewModel을 가집니다. 의존성을 가질 수 있지만, Component는 아니죠."
이게 핵심입니다. Component는 비즈니스 로직을 갖지 않고 단순히 여러 화면에서 사용하고 있는 요소를 Widget을 조합하여 생성하였기에 비즈니스 로직이 존재한다면 굉장히 구현이 까다롭습니다.
어디서는 전체 목록을 불러와서 ListView를 만들고, 어디서는 내가 작성한 목록만을 불러와서 ListView를 만들텐데, 이 ListView를 ViewModel의 의존성을 추가해서 작성하면 좀 큰일이 날듯합니다.
UI를 설계하며 각각의 요소를 분리하는 것은 재사용성을 높이고 효율적인 코드 작성으로 이루어집니다. 반드시 위 내용이 정답이 될 순 없지만 튼튼하게 코드를 설계하여 삶의 질을 높여봅시다.