ㅤ 모브 크로스핏 7시반 사람들과 함께 갓생 챌린지를 4주동안 진행했다. 이번에 참여하기 전부터 거의 상시 진행되는 챌린지였는데, 이번에 처음 들어갔다. 이번 차수가 무려 11기라고 한다. 처음부터 꾸준히 해온 사람은 거의 1년이 넘게 갓생을 살아온 것 아닌가…? ㅤ 규칙은 간단하다. 주 1회 ~ 5회 수행할 목표를 최소 1개씩 정하고 인증을 올린다. 일요일 저녁에 이번주 결산을 하고, 성공하지 못한 목표 하나 당 5천원을 벌금으로 낸다. 매 주 끝날 때 마다 이번 주에 대한 느낀점을 간단하게 남긴다. 그런데, 효과는 굉장했다. 이게 선언효과 + 패널티로 돈이 걸림 + 서로의 노력에 대해 격려하고 반응을 남겨줌 의 시너지가 체감이 크게 되었다. 뭐랄까, 4주동안 매일매일 내가 하는 행동을 의식하고 있게 ..
ㅤ 최근에 해결하는데에 꼬박 4일이 걸린 문제가 있었다 ㅜㅜㅜㅜㅜ ㅤ 뷰에서 작은 컴포넌트 위젯에서 GestureDetector를 통해 PanGesture를 인식하고, 터치 좌표값을 받아다가 뷰에게 전달하고, 뷰에서 이를 받아다가 setState로 값을 수정하면 다른 위젯에서 이 값으로 UI를 그리는 로직을 작성하고 있었다. 대충 그림으로 그리면 아래와 같다. ㅤ 이를 위해서 대략적으로 아래 플로우로 실행을 제어하려고 했다. View에서 GestureDetector가 달린 위젯에 콜백함수를 전달 onPanUpdate 시 콜백함수 호출 콜백함수에서 setState 실행 뷰 다시 그리기 position UI 반영 ㅤ 그런데 왠걸? onPanUpdate 함수가 1-2번 호출되고나면 콜백함수가 더 이상 실행되지..
ㅤ 처음에 클린 아키텍처를 프로젝트에 반영하려고 하면서 어떻게 구조를 설계해야하나 고민을 할 때, 아래같은 내용을 담은 적이 있었다. 그리고, 이게 다시 한 번 불편하다고 느낀 상황이 와버렸다! ㅋㅋㅋ ㅤ 아래 이미지처럼 import 문의 크기를 줄이기 위해 열심히 GBDF를 적용해 간소화를 적용하고 있었다. ㅤ 그런데, 저렇게 줄이고 나니깐 각 파일에서 어떤 계층을 참고하고 있는지 더 선명하게 보이기 시작했다. 다시 말하자면, domain 모델에서도 data 계층의 파일들을 import 하여 사용하고 있는게 더 눈에 잘 띄기 시작했다. ㅤ 물론 이게 riverpod 방식으로 파일 구조를 짜려다보니, 앞서 올린 고민 이미지에서 그린 것 처럼 domain에서 data에서 작성한 파일을 필연적으로 impor..
너무나도 객체지향스러운 방식인 오버로딩을 다트 언어에서는 사용할 수가 없었다. 나는 코드를 가독성 넘치면서 깔끔하게 작성하는데에 있어서 오버라이딩, 오버로딩만큼이나 유용한 도구가 없다고 생각했는데, 요런게 제공이 잘 되지 않다보니 좀 불편함을 느끼게 되는 것 같다. ㅤ 아래가 내가 희망하던 코드의 방식이고 // 내가 짜고싶은 코드 List getEntityList({ DateTime bySelectedDate, }) { ... } List getEntityList({ String bySelectedUserId, }) { ... } // -> 이걸 사용하는 시점에는 list = getEntityList(bySelectedDate: DateTime); list = getEntityList(bySelected..
Data Layer 쪽의 리펙토링을 진행하면서, 내가 데이터 계층의 Repository Impl 클래스를 파이어베이스에 의존적이게 코드를 작성하고 있다는 걸 깨달았다. 클린 아키텍처의 의의를 ‘쉽게 갈아끼울 수 있는 백엔드와 프론트엔드’ 라고 생각하고 적용하려고 노력하고 있기 때문에, 범용 클래스를 무조건 “특정 서비스에 의존적이지 않은 형태”로 작성해야 한다고 생각한다. 이에 요걸 분리하기 위해서 여러가지 고민을 했고, 이걸 글로 남겨두려고 한다! ㅤ 현재 계층 구조와 설계한 사용 모델들을 간략하게 써보면 아래와 같다. Presentation Layer에서는 뷰 계층의 model을 사용한다. Domain Layer에서는 Entity를 사용한다. Data Layer에서는 데이터 계층의 model을 사용한..
파이어베이스에서 데이터를 받아올 때 시간과 날짜를 나타내는 자료형이 Timestamp였고, 플러터에서는 Datetime을 사용하고 있었다. 나는 Timestamp가 flutter(dart)의 내부 클래스이고, datetime과 timestamp가 같은 타입이라고 생각했는데, Timestamp는 Firestore 프레임워크에 포함된 타입이며 datetime으로 사용하기 위해서는 명시적으로 형변환 과정을 거쳐야 하는 것을 확인했다. ㅤ 검색해서 찾다보니 누군가는 Timestamp가 더 세밀한 초 (millisecond)를 표현할 수 있는 자료형이라고 했는데, 파이어베이스에서는 초 단위까지만 입력이 가능하고, DateTime 클래스의 프로퍼티에 microsecond 단위의 데이터를 넣을 수 있는 것으로 보아서..
열심히 프로젝트 구조를 클린 아키텍처 구조로 개선하고 있다. 내가 싼 똥이 점점 정리되는 중이라고 느껴진다. 뭔가 다시 작업을 시작하면 더 깔끔하고 편리하게 작업을 진행할 수 있을 것 같은 느낌이랄까…? ㅋㅋㅋㅋ ㅤ 그래도 나름의 고민을 거듭하면서 구조를 개선해나가고 있는 중이다. 이번 차례에는 Data Layer에 대한 대공사를 진행하고 있는데, repository - repository impl - datasource 의 관계를 어떻게 구성하는게 적절한 지에 대해 고민을 열심히 하고 있다. ㅤ (대충 뭔가 호작질중) ㅤ 그렇게 설계한 2번째 구조는 아래와 같다. ㅤ 먼저 repository와 repository impl은 1대1 관계로 작성해주었다. 각 repository는 interface로서 구현..
ㅤ 클린 아키텍처를 적용하기 위해 기존의 프로젝트를 리팩토링 하고있다. ㅤ 기존에는 각 기능(뷰) 별로 폴더 내에 presentation, domain, data 세 가지 layer를 모두 배치하고, 각 계층 내에 필요한 폴더를 따로 만들어서 관리하고 있었는데, 여러 기능에서 공유되어야 하는 usecase가 하나의 기능 폴더에 귀속되어 있어 다른 기능쪽에서 끌어서 사용해도 되나? 라는 걱정이 많이 되었었는데, 요런 부분들을 타파하기 위해 완전 구조 개선을 시도하고 있다. ㅤ 개선을 시도한 내용은 아래와 같다. 모든 폴더에 따로 놓여있는 모델 → Entity로 이름을 바꿔 한 폴더에서 관리하기 동일한 개념이지만 여러 개로 구현되어있는 모델은 하나로 정리하기 여기저기 흩어진 usecase를 한 폴더에서 관리..