악보에 대해 CRUD 구현을 완료했다.
그리고 백엔드를 오라클 클라우드를 이용한 리눅스 서버에서, BaaS인 파이어베이스로 이전했다.
Firebase 로 이전한 배경
악보에 대해 수정과 삭제를 진행하기 위해서는 악보를 작성한 작성자를 구분할 수 있어야 한다.
유저 인증 기능을 손수 구현한다면 내가 생각하기에 DB에 아이디와 비밀번호를 저장해놓고
사용자가 입력하면 입력값을 DB의 데이터와 단순 비교하여 체크하는 방식으로 했을 것이다.
비밀번호의 경우, 데이터를 그대로 저장하는게 아니라 해시를 사용한다고 들었다.
또 여기저기에서 주워들은 이야기로는 토큰이니 세션과 쿠키니 그런 것으로 유저 인증을 한다고 들었는데,
"아이디 + 비밀번호 + 해시" 이 3가지 조합외에 기술을 사용하는 이유는 아직 와닿지 않았다.
(나중에 웹개발 공부를 하다보면 이해할 수 있을 것이라고 생각한다..ㅎㅎ)
하지만 이걸 직접 구현하기에는 아직 내 실력이 거기까지 이르지는 않았다고 생각했고,
이 앱은 실제 플레이스토어에 출시를 하는 것이 목적이기에 보안이 중요하다고 생각했다.
또한 자체 회원가입 시스템보다 구글, 페이스북, 카카오 등의 기존 계정 정보를 활용하는 방식이
사용자 편의성이나 보안 등에 대해서 더 좋다고 생각했다.
무엇보다도 백엔드를 수정한 가장 큰 이유는 데이터 전송 속도에 대한 문제였다.
지금이야 나 혼자 데이터를 만들고, 데이터를 읽으니 속도 문제가 체감이 되지 않지만,
만약 유저가 많아지고 서버에 트래픽이 많아지면 현재 오라클 클라우드로는 버티기 힘들 것 같다는 생각이 들었다.
오라클 클라우드 사용 후기를 봐도 속도가 느려서 답답하다는 의견이 많았던 것으로 기억한다.
그래서 데이터 처리 속도 개선을 위해 파이어베이스의 클라우드 DB인 파이어스토어를 사용하기로 결정했다.
막상 파이어 스토어를 써보니 굉장히 좋았던 점은, 바로 DB가 자동으로 갱신된다는 점이다.
StreamBuilder 위젯을 이용하여, DB에 스트림을 연결해두고, 데이터가 변경될 때마다 알아서 builder가 호출된다.
오라클 클라우드를 쓸 때는 악보를 추가하고나서 악보 목록이 자동갱신되지 않았었다.
그래서 악보 목록을 수동으로 갱신해야만 했는데 파이어 스토어는 그 문제를 깔끔하게 해결해주었다.
한가지 고생했던 점은, 그동안 MariaDB와 Oracle 을 쓰면서 RDMBS에 익숙했었는데,
FireStore가 NoSQL을 사용한다는 점이었다.
테이블과 테이블의 조인으로 데이터를 조회하며, 데이터는 중복성을 최소화 하여 저장하는게 아니라,
(RDBMS에서는 정규화가 중요하다고 알고 있다.)
오히려 데이터를 중복해서 저장한다는 방식이 새로웠다.
구글의 FireStore 영상을 봤는데 개인적으로 NoSQL의 장점이 와닿아서 이 방식을 쓰는데 거부감이 없었다.
CRUD시스템에서 당연히 Create 하는 경우보다, Read 하는 경우가 매우 빈번한데,
NoSQL의 경우, 데이터를 중복 저장하는 문제를 안는 대신 Read 속도를 매우 빠르게 늘렸기 때문이다.
내가 만드는 앱 역시 악보를 만드는 경우보다, 악보를 보는 경우가 훨씬 더 많기에 이 장점이 크게 와닿았다.
적용 결과
오준석의 플러터 생존코딩, 인터넷 검색을 적극 활용하여
파이어 베이스 등록과 설정을 마치고 적용한 모습은 다음과 같다.
(개인적으로 인터넷 검색도 도움이 되었지만, 생각보다 책 내용이 도움이 많이 되었다.)
파이어스토어 상의 DB 모양이다.
현재는 구글 로그인만 구현해뒀는데, 이 경우 구글 이메일로 유저 구분이 가능하다.
(그래서 구글 계정 외 다른 계정 로그인을 도입하는게 나은지 고민중이다
구글 정보로 인증을 진행하고 DB에서 데이터를 조회하는데,
다른 계정이 들어가면 로그인한 플랫폼을 추가로 구분해야 할 것 같아 복잡해질 것 같았다.)
로그인 버튼 디자인은 간단하게 했는데, 나중에 구글틱하게 수정할 예정이다.
(구글 로고도 넣고, '구글로 로그인하기' 문구도 넣고, 배경색도 바꾸고)
로그인을 한 결과이다.
내가 만든 악보의 내 악보 리스트 디자인은 나중에 수정할 예정이다.
리스트 아이템의 사이즈를 체크하기 위해 일부러 회색으로 표시했다.
우선 이 화면에서는 내가 만든 악보를 최근 만든 악보 순으로 3개를 보여주고,
'내가 만든 악보' 버튼을 클릭해 더 자세히 볼 수 있도록 만들고자 한다.
똑같이 좋아요 표시를 한 악보도, 최근 좋아요를 표시한 악보 3개를 보여주고,
'좋아요 표시한 악보' 버튼을 누르면 자세한 리스트를 볼 수 있게 만들 것이다.
이 디자인은 유튜브 뮤직을 참고하였다.
(사실 많이 베껴서 만든 것 같다ㅋㅋ)
내가 만든 악보의 리스트 아이템에는 악보 수정과 삭제 버튼을 만들었다.
악보 수정은 새악보 추가, 악보 뷰어 기능에 썼던 클래스를 그대로 재활용했다.
새 악보 추가, 악보 뷰어, 악보 수정은 같은 클래스의 객체를 생성하는 것으로 만드는데,
이에 대한 구분은 간단하게 했다.
악보 ID가 없는 경우 => 새 악보 추가
악보 ID가 있는 경우 => readOnly 속성이 true => 악보 뷰어
악보 ID가 있는 경우 => readOnly 속성이 true => 악보 수정
악보 삭제의 경우도, 악보 ID를 기준으로 컬렉션에서 문서를 지우는 방법으로 했다.
이것으로 악보에 대해 CRUD를 모두 구현했다.
그 밖에 수정한 것
새로운 기능을 추가하는 것 외에도 기존 기능을 수정하거나, 프로그램 구조를 수정하였다.
(사실 올림픽을 보느라 전만큼 코딩하는 시간이 늘지 않아서 일주일동안 많은 걸 하진 않은 것 같다ㅋㅋ)
첫 악보 검색 화면의 상단을 사진처럼 수정했다.
이 디자인은 어디서 많이 본 것 같겠지만..
구글 플레이스토어를 참고해서(베껴서) 만들었다
악보 수정할 때 키보드의 디자인도 조금 바꾸었다.
상단의 최근 입력한 코드를 저장하는 부분의 디자인을 수정하여
입력할 코드를 미리 저장해두고, 저장한 코드를 입력할 수 있도록 했다.
x4는 앞의 4개 코드를 입력, all은 저장된 모든 코드를 입력하는 기능인데,
Verse
A B C D
A B E F
Chorus
A B C D
A B C D
이런 구조로 송폼이 짜여있을 때를 대비해서
처음에는 최근 입력한 코드 x4, x8 입력으로 나누어서 디자인했었다.
그런데 이렇게 디자인 해놓고 실제 사용을 테스트하기 위해
아이유의 '내 손을 잡아' 코드악보를 직접 작성해보니..
chorus 부분의 코드가 4개 8개로 딱 떨어지는 경우는 드물다는 걸 깨달았다.
(단순한 코드진행에만 사용 가능한 버튼이었다.)
저렇게 코드가 구성되어 있을 때 4개 8개로 개수를 딱딱 나눠 저장하고 입력하는 것은
오히려 더 비효율적이고 불편하기만 했다.
그래서 x8 버튼을 빼고, 코드 저장개수 한도도 8개에서 24개로 늘린다음
그냥 저장해둔 모든 코드를 한번에 입력하는 기능으로 수정했다.
또한 원래는 내가 입력한 코드를 자동으로 모두 담아두도록 했는데, 이 방법이 생각보다 불편했다.
"내가 입력한 코드"를 구분하기 위해, 각 셀의 포커스가 해제될 때, 코드를 새로 담도록 했는데,
가사를 수정하거나, 실수로 잘못된 셀을 터치했을 때도 코드가 새로 담겨버려서 불편했다.
그래서 사용자가 직접 사용할 코드를 담도록 수정했고, 이게 더 편했다.
또 지금 생각해보니 저 x4 버튼도 쓸모가 없는 것 같다.
어차피 verse, chorus 를 페이지별로 나누어서 작성하게 유도할 생각이었는데,
한 페이지 내에서는 코드가 다 비슷하게 진행되기 때문에 굳이 개수를 정할 필요 없이
항상 저장한 코드 진행 모두를 그대로 붙여넣을 수 있도록 하는 게 더 나아보인다.
또 사용자를 위한 도움말 페이지도 만들었다.
각각의 아이콘버튼이 어떤 기능을 수행하는지 적어두었다.
아직 코드 키보드에 대한 설명은 적지 못해서 그 부분을 추가할 예정인데,
이렇게 단순히 일렬로 나열하는 방식보다,
코드 입력에 대한 부분은 다이어로그 내부에서 탭으로 나누어 만들면 어떨까 고민하고 있다.
프로그램 구조 역시 수정했다.
이렇게 클래스를 종류별로 모으고, 하나의 dart 파일 안에는 하나의 클래스만 들어있도록 만들었다.
이렇게 프로젝트를 만들면서 프로그램 구조에 대한 고민도 정말 많이 했다.
Provider 라는 것은 원래 디자인 패턴 중 하나이자
BloC와 더불어 플러터 프레임워크의 주요 상태관리 라이브러리 중 하나인데,
이 두 라이브러리는 'UI와 비즈니스 로직의 분리' 라는 목적 아래에서 탄생한 라이브러리이다.
처음에 프로바이더를 쓸 때는 단순히 편하게 다른 위젯의 상태를 가져오고, 갱신하려고 썼다면
지금은 프로그램의 구조적인 관점과, 그 사용 목적을 고려하여 프로바이더를 어떻게 써야할 지 고민하게 되었다.
각각의 칸을 디자인 하는 chordCell 위젯이 있고, 이 위젯은 나에게 있어 'UI' 그 이상도 이하도 아니었기에
이 위젯만큼은 가능하면 provider와 분리하여 관리하고자 하였으나, 개발을 하던 중 몇가지 문제가 발생했다.
우선 함수 구조의 통일성 문제가 있었다.
새로 칸을 추가하면 ChordCell 객체를 추가하고,
이 객체에 담는 데이터인 '코드', '가사' 를 저장할 데이터도 리스트에 추가해야한다.
그래서 Editor에서 코드셀을 추가하는 버튼을 터치하면
1. 프로바이더 내 데이터에서 코드와 가사를 추가
2. 에디터 위젯에서 별도로 ChordCell 위젯 객체를 추가
이렇게 두가지 과정을 거쳐야 했다.
이 문제는 코드셀 추가뿐 아니라 삭제,수정, 변경 모든 부분에서 동일하게 발생했고,
만약 ChordCell 위젯을 프로바이더에서 관리하게 된다면,
프로바이더 내부에서 단 한번의 함수 호출로 깔끔하게 기능을 구현할 수 있었다.
또 코드 키보드에서 직접 코드셀을 추가하는 기능을 만들다보니
코드셀을 추가하기 위해 '에디터'라는 부모 위젯의 상태를 직접 가져와 써야하는 문제도 발생했다.
이 역시 ChordCell 위젯을 에디터라는 상위 위젯에서 관리하다보니 생기는 문제로,
프로바이더에서 ChordCell을 관리하면 해결될 문제였다.
이 두가지 문제 때문에, 결국 ChordCell 이라는 작은 단위 위젯 UI를 프로바이더로 관리하게 되었다.
그러나 UI와 비즈니스 로직의 분리라는 관점에서 이게 맞게 구조를 짠 것인지는 아직도 확신이 서지 않는다.
또 맨 처음 프로바이더를 사용할 때, ChordCell 객체도 그냥 프로바이더로 관리할지 말지 고민하다가
생각하기가 귀찮고, 코드도 바꾸기 귀찮아서(...) 그냥 별도로 관리했었다
그냥 이럴거면 처음부터 ChordCell 객체까지 프로바이더로 관리했다면
시간 낭비를 안하지 않았을까 하는 생각이 들었다.
프로그램 아키텍쳐를 설계하고 난 다음에 코드로 구현해야 하는 이유를 다시한번 절실히 깨닫는다..
전 배달의 민족 리드 개발자이자, 현재 인프런에서 개발자로 일하고 계신 이동욱 님의 유튜브 채널
개발바닥에서 객체지향과 관련해 인프런 강의를 추천해 주신게 있었다.
강의 내용이 굉장히 좋아 자기 팀원들에게 모두 보라고 하셨다고 해서 1강 미리보기를 봤다.
1강 강의소개 부분에서 강사님이 말씀하시기를
시간이 지날 수록 프로그램에 코드가 추가되는 양은 줄어들지만, 한줄의 코드를 추가하기 위해 드는
(시간적인 부분을 포함한) 비용은 기하급수적으로 늘어난다고 한다.
난 아무래도 그 강의를 꼭 사서 봐야할 것 같다는 생각이 강하게 들었다..ㅋㅋ
바로 2달전에 학교에서 '객체지향 프로그래밍' 수업을 듣기까지 했는데도 아직 배워야할 게 많은 것 같다.
이제 정말 중요한 기능들은 대부분 구현이 되었다.
'그룹' 부분과, 악보 검색 기능, 내가 좋아요 표시한 악보를 조회하는 기능,
악보에 좋아요 표시하는 기능을 만들면 기본적인 기능은 끝이다!
그럼에도 아직 실제로 앱을 출시하기에는 부족한 부분이 많다.
사용하다보니 악보를 작성하는 과정에서 버그가 계속 튀어나오고 있고,
악보를 조회하는 기능도 단순히 '전체 리스트에서 노래 제목으로 검색' 하는 기능 뿐이다.
과연 군대가기 전에 구현할 수 있을 지는 모르겠지만..
악보에 난이도를 매기고, 난이도별로 조회, 가수별로 조회, 노래 key별로 조회, 인기순으로 조회, 장르별 조회
이런 식으로 검색 조건을 세분화하고, 첫 페이지에서 각 조건별로 악보를 추천하는 디자인도 구상 중이다.
물론 이 아이디어 역시..
플레이 스토어 메인화면 아이디어를 참고했다.
게임에도 여러가지 장르가 있고 각각의 특징이 있기 때문에 나누어서 보여줄 수 있듯이
악보도 각각에 특징에 맞게 나누어서 보여주면 좋을 것 같다고 생각했다.
우선 이런 기능들은 부가적인 기능들이라고 생각하면서 가장 근본적인 기능인
1. 악보 작성의 편의성
2. 악보 조회의 편의성
이 두가지 기능을 제대로 구현하는데 집중하려고 한다.
악보 조회야 지금은 큰 기능이 없어서 버그도 없지만,
악보 작성은 이런 저런 기능이 워낙 많다보니 버그도 난무하고 있다.
(테스트로 악보를 작성해보려고 하면 버그발생,
버그 수정하고 다시 테스트하려고 하면 버그발생..)
버그 없는 프로그램은 없겠지만, 적어도 핵심 기능에서만큼은 큰 버그가 없도록 만들고 싶다.
'개인 프로젝트 > [2021] 코드악보 공유APP' 카테고리의 다른 글
17. UI 수정 / 악보 좋아요 기능 추가 / 그룹 기능 추가 / 성능 개선 (0) | 2021.08.19 |
---|---|
16. 악보 구성 수정, 악보 검색 기능 추가 (0) | 2021.08.07 |
14. 악보 편집 기능 만들기 - UI수정, Provider, 편집한 악보 저장 (0) | 2021.07.21 |
13. 악보 편집 기능 만들기 - 커스텀 키보드로 입력한 코드 띄우기, 깃허브 연결, DB에 테이블 추가 (0) | 2021.07.18 |
12. 악보 편집 기능 만들기 - 커스텀 키보드 토글 버튼 기능 구현 (0) | 2021.07.16 |