본문 바로가기

안드로이드 개발 일기

안드로이드 개발 일기 2 - 핵심은 기본기

안드로이드 개발을 시작하고 여러 사람을 봽기도 하고 짦은 시간안에 다양한 경험을 했던 것은 놀랍다. 뒤돌아 생각해보니 사이드 협업프로젝트 4개, 외주 큰 일 2개, 개인앱 3개, 공모전 2번 수상 등등 개발을 좋아했던 마음은 다채로운 경험을 하게 도왔고 정신 차려보니 가슴을 뛰게하는 스타트업에 와서 열정을 불태우고 있었다. 

회사의 일을 함부로 언급해서는 안되지만 그나마 언급할 수 있는 것은 기존 리액트 네이티브로 만든 앱에서 네이티브로 전환점을 가지는 시기에 안드로이드 개발자를 채용하였고, 회사의 재밌는 사업 아이템이 진정 스타트업의 느낌이 물씬 나서 감히 채용에 도전했었다. 

고맙게도 이 회사는 나를 반겨주었다. 

문제는 기존 리액트 네이티브 앱을 버리고 새롭게 네이티브로 시작하는 건 단순하게 말하면 안드로이드 스튜디오에서 새로 프로젝트를 만들어 시작하는 일인 것이다. 처음부터 만들어야하는 것부터 개발자로써 가슴 뛰게 만들었고 진정한 명작을 만들어보자 라는 열정하에 쓸줄 모르던 Hilt 와 한참 유행이라던 AAC 라이브러리를 활용한 안드로이드 권장 아키텍처에 대해 공부를 했다.

하지만 회사에서 정해주는 일정이란게 있었고, 서버 개발자, 디자이너, UX 기획자와 꾸준히 소통을 하며 합을 계속 맞춰가야 하기 때문에 수정이 계속 반복될 것이 분명했다. 그래서 내 역량 대비 정해진 기간안에 좋은 소프트웨어 만들 수 있을까 라는 고민이 컸었다.
그렇지만 "남자가 칼을 뽑으면 무라도 썰어야지?" 라는 마음에 퇴근이라는 개념도 없이 모든 시간을 쏟아 부었다. 

아래는 그 이후의 이야기다.

1. 나의 큰 실수들

나의 실수부터 정리하려고 한다. 이 글은 오답노트 용으로 똑같은 실수를 반복하지 않기 위해 작성한 것이기 때문이다.


(1) 잘못 이해한 리팩토링 기법 + 중구난방 옵저버 패턴을 적용한 페이지

앱 제작 초반에 마틴 파울러의 리팩토링이라는 책을 보기 시작했다. 책의 절반은 마틴 파울러의 생각를 배울 수 있었고 많은 도움이 됬다. 문제는 책의 나머지 절반은 리팩토링 기법들을 소개하는데 이 기법을 잘못 이해하고 적용한 것들이 문제였다.

당시에 MVVM를 잘못 이해하고 있어서, 다시 공부하고 있었다. 그리고 리팩토링 책에 적힌 것은 가능하면 함수를 분리하라 였다. 그래서 최대한 함수를 무.조.건 분리하는 것이 좋구나 라고 일시적으로 잘못 이해한적이 있었다.


나눌 필요도 없는 구문을 함수로 다 분리시켜버렸다. 거기에 잘못 이해한 MVVM방식의 불필요한 옵저버 패턴 기법도 섞여버리니 데이터 흐름이 어디서 시작되고 오가는지 아예 이해하기 힘든 총제적 난국이 되어버렸다. 다행히도 페이지 하나에서만 위 같이 코드를 짠것이다.

일주일 뒤에 엄청 잘못된 방식으로 작성된 코드인 것을 깨닫고 땅을 치고 후회했다. 그 이후에 해당 페이지를 간혹 리팩토링을 해서 그나마 불필요한 코드가 많이 줄었으나, 일정상 많은 리팩토링을 하지 못했고 지금도 해당 페이지의 수정요청이 들어올까봐 아찔하다.

 


(2) 재사용 UI 컴포넌트를 많이 만들지 않은 것

디자인/기획에 대해 공통화가 되지못해서 초반에 적용하지 않아서 지금 상황에 왔다....? 치사하게 남탓(?)을 할 수도 있지만 결론은 내 잘못이 크다. 훌륭한 개발자는 변경에 있어서 대비가 되어야 된다고 생각한다. 특히 안드로이드는 코드 전반적인 설계기법도 좋지만, 뷰의 재사용 , xml 의 재사용, resource 의 재사용을 염두 하는것이 매우 중요하다.

그래서 style, theme, Custom View로 모듈화해서 디자인에서 반복적으로 사용이 될 수 있는 UI들을 정리해서 공통으로 쓰고 확장까지 가능하게 미리 토대를 잡아놨다면 매우 좋았을 것이다. 


디자인이 수시로 변하는 것 같아서 만들지 않았다. 그래서 대부분 xml이 쌩 노가다가 이루어졌다. (물론 Done 버튼이나 Haeder 부분은 최소한 style을 만들어 공통적으로 썻지만)

그래도 이전 조금의 짠밥(?) 이 있어서 디자인적으로 반복되는 item 이나 adapter 를 미리 캐치해서 공통적으로 만들어 놓고 쓰긴 하지만 나머지 xml 노가다 성이 생산 속도의 발목을 잡고 있다.

 

(3) 복잡한 여러 페이지를 모두 하나의 AAC ViewModel을 사용

나는 당연하게 안드로이드 Jetpack에서 제공하는 ViewModel를 사용했다. 어느날 여러 페이지가 연관되는 화면에서 ViewModel를 하나만 사용했는데, 

그랬더니..? ViewModel이 하나의 복잡한 페이지만 담당해도 많이 뚱뚱한데 여러 페이지에 하나의 ViewModel로 통합해서 쓰려고 하니, ViewModel 내의 변수가 매우 많아지고 ViewModel의 데이터 흐름을 점점 읽기 힘들어 지며 변수도,, 공용 스탯이라서 서로의 변수를 건들게 되면서 미래에 통제할 수 없는 지경까지 이를까봐 무서웠다. 

그래서 다른 페이지는 가능하면 ShareViewModel를 사용하는 것은 적은 로직이 들어간 화면이 아니면 사용하지 않거나, Dialog에서만 사용하게 되었다. 분리는 아름다운 것이다.

 


(4) Compose UI 로 변환 염두한 DataBinding 

Compose 는 정식 출시전 부터 안드로이드 개발자 사이에서 뜨거운 한 소재였었다. 나도 Compose에 관심이 많았고, 개발중인 프로덕션 출시 후 리팩토링 -> 반응형 프로그래밍 심화 도입 -> Compose 순으로 도입하리라 마음먹었다. 
 
그래서 개발 초반에 xml 을 활용하지 않는 ViewBinding 으로 UI를 만드려고 했으나, 나의 기량상 작업속도가 나오는 DataBinding을 사용하기로 목표를 바꿧다. 언제나 Compose로 변환을 다짐하고 작업을 했기 때문에 DataBinding을 깊게 사용하지 않으려했고, BindingAdapter 나 xml에 가능한 많은 로직을 넣지 않고 최대한 데이터 set정도로만 사용하려했다.

 

그렇게 한가지 갈피를 못잡고 애매하게 DataBinding을 사용하다보니 DataBinding을 통해 쉽게 해결할 일을 다르게 해결했다. (DataBinding을 애용하는 사람들이 보면 비효율적인 코드들을 보고 욕할 것 같다.) 그리고 Compose 가 정식 출시 되었지만 알고 보니, Compose 는 제대로 활용해야 좋은 것이었고 레퍼런스가 적기도하며 애매하게 썻다가 안쓴것보다 못한 녀석이었다. 

Compose 에 대한 사설 레퍼런스가 확실히 채워지고 사용하려고 하는데 실제 프로덕트로 사용하기 위한 레퍼런스 채워지는데 최소 1년~3년이 걸릴탠데, 차라리 그 전에 DataBinding 를 제대로 써서 멋진 코딩하면 좋았을 것을,,, 아쉬움이 남는다.

 

(5) 손이 부족했고, 완벽하게 사용못한 Room 을 이용한 데이터 캐싱처리

안드로이드 권장 아키텍처에서 Room 을 이용해서 데이터를 캐싱하는 방식이 나온다. 개발 초반에 해당 방식을 도입을 시도했었다. 캐싱처리를 하니까 정말 네트워크가 일시적으로 죽어도 로컬에 저장된 데이터 리스트들이 화면에 렌더링 하는것을 보며 신기했었다.
 
하지만, 모든 부분을 데이터 캐싱처리 하려했던 것이 문제였다. 프로덕션에 도입하는 데이터는 흔히 블로그 예제로 쓰는 데이터와 달리 많은 Join 이 이루어져 오는 경우가 많다. 만약 A Model 과 B Model 를 Join 해서 C Model 형태로 왔을 때 각각 로컬용 Model의 A , B 에 담아야하는건지 애매했다.
 
그외에도 복잡한 데이터를 모두 데이터 캐싱처리를 하려다보니 상당 부분 손이 매우 많이 갔다. 그리고 Room을 다루는데 있어서 기량 부족인지 몰라도 간혹 버그가 생기기도 하는데  또 시간이 걸린다. 첫 API 사용시 실수 때에도 내가 파싱을 잘못한건지, 리스폰스를 잘못아는건지, 리퀘스트를 잘못하는건지, 등등 체크해야하는데 로컬 부분 오류까지 생기면 매우 작업 속도를 뎌디게 헀다. 그래서 결국 우선 포기했다.

지금 생각해보면 원격 -> 로컬을 캐싱처리하는 몇가지 공통 컴포넌트를 따로 만들어 한번에 처리했어야한다. 출시 후에 반드시 적용하고 싶다.

 

2. 개발 후기

(1) 최소한의 아키텍처는 반드시 필요하다.

소프트웨어를 개발하다보면 정말 많은 수정이 이루어진다. 한번은 서버 Api 의 대거 수정이 이루어졌다. 여기서 큰 도움을 받았던 것은 레포지토리 패턴이었다. ViewModel 은 Data에 관해 레포지토리만 알고 있는 상황이었다.

Api 수정전에는 Api 하나를 가지고 여러가지 데이터를 불러오는 형식으로 했었다. Request를 넘겨서 판매용인지, 구매용인지 등등을 구별해서 사용하고 있었다.

 그래서 Repository에서 해당 Api 의 여러 인자들을 넣었을 때의 데이터 Response를 다 만들어놨었다.

fun getSellList() = dataSource.getDataList(type = TYPE.SELL)

fun getBuyList() = dataSource.getDataList(type = TYPE.BUY)

fun getSoldList() = dataSource.getDataList(type = TYPE.SOLD)

ViewModel 에서 어떠한 인자를 넘길 필요 없이 Repository에서 만들어둔 상황에 맞는 DataList를 사용하도록 했다.
하지만 갑자기 서버 Api가 바뀌었을때 Request를 넘기지 않고 해당 리스트를 가져올 수 있도록 변경이 되었다.

fun getSellList() = dataSource.getSellList()

fun getBuyList() = dataSource.getBuyList()

fun getSoldList() = dataSource.getSoldList()

DataLayer를 수정을 해도 Api가 바뀌어도 ViewModel 의 로직은 변함이 없었다. 그저 Repository에서 정의한 함수를 그대로 가져다 쓸 뿐이었기 때문이다. 


나는 아키텍처에 대해 많이 부족하다. 나중에 깊게 파보고 싶은 분야 이다. 확실한건 잘 모르더라도 최소한의 레이어 구분은 필수다. 그것이 나의 생산속도를 유지해주었다.

 

(2) onDraw 삽질

안드로이드 개발을 하다보면 기본적으로 서버에서 받는 Api 데이터를 UI 로 만드는 일을 많이하게 된다. 간혹 기본 제공 되는 UI로 만드는 것이 불편하거나 불가능할 때 특정 View 혹은 View를 상속받아 onDraw 장인질을 해야한다. 현재 개발중에 Custom View가 한 2~3개 정도 들어간 것 같은데, 열심히 정말 열심히 장인질을 했던 것 같다. 

 


(3) 재사용 모듈 제작은 언제나 진리다.

너무 당연한 얘기겠지만 후기임으로... 항상 공통된 로직을 처리할 모듈은 개발 속도를 크게 향상 시킨다. 대표적으로 페이징 처리가 필요한 경우를 대비해 페이징 처리 공동 모듈을 만들어두니 너무 편했다. Kotlin의 경우 익스텐션을 응용하는 것이 너무 편하다. 

 

 

(4) 언어 사용 기본기가 중요하다.

매번 느끼는 것이지만 다시 느꼈다. 내가 사용하는 언어 Kotlin 은 함수형 프로그래밍의 파워도 가지고 있는데, 이를 완벽하게 활용했는가? 라고 묻는다면 No 다. Kotlin을 함수형 답게 완벽하게 썻다는 기분이 전혀 안든다. 최소한 언어의 장점을 잘 응용 했다면, 정말 만족할만한 프로젝트가 됬을 것 같다. 

Kotlin의 장점을 최대한 이끌어 내는 개발자가 되려고 한다. 당분간 Kotlin에 매진할 예정이다. 

 

(5) 집중력을 유지하자

코딩을 하다보면 내 자신의 양심과 싸울 때가 있다. 컨벤션을 어기기도 하고, 별 생각 없이 액티비티에 모든걸 만들어버리고 싶기도 하다. 변수명도 대충 짓고 후딱 넘기고 싶다. 요즘 PR을 필수로 하는 회사가 많이 생겨서 함부로 컨벤션을 무시하기도 힘들기도 하지만 혼자 개발하는 사람이 많은 소기업의 앱 개발자는 유혹에 벗어나기 힘들다.

 

실제로는 현재 나와 미래의 나 자신이 협업을 하고 있는 것이었다. 

 

예를들어 A~ Z 페이지가 있다고하자 알파벳 순으로 작업을 하다보면, 언젠가 A라는 페이지를 다시 봐야하는 순간이 있다. A 라는 페이지를 만약 개발 출시 후 3달 뒤에 봤을 때, 과거의 내가 작성한 코드를 바로 이해할 수 있을까? 

실제로 Z 페이지 마무리 쯤에 A 페이지를 다시 봐야하는 경우가 있었다. 해당 페이지를 보고 오랜만에 보는 페이지라 마치 내가 아닌 다른 사람이 작업한 코드처럼 느꼈다. 다행이도 이 프로젝트에서 정한 컨벤션으로 코딩이 되어있어서 금방 이해할 수 있었다.

 

 

 

 

'안드로이드 개발 일기' 카테고리의 다른 글

안드로이드 개발 일기  (0) 2021.05.18