나만의 가계부 만들기 (With Vanilla JavaScript)

Dengo·2022년 8월 14일
1

Project

목록 보기
1/3
post-thumbnail

개요

바닐라 자바스크립트를 사용하여 웹페이지 만들기에 도전했다.
주제는 달력을 갖고 있는 가계부 만들기 이다.
웹 페이지는 HTML, CSS, JavaScript만을 사용해서 만드는 것을 목표로 했고
백엔드는 express와 경량 db를 사용해서 만들어 보았다.
원하는 기능을 전부 만들지는 못한 미완성 이지만 일단은 글을 남긴다.

TODO LIST

홈 화면
✅ 달력 만들고 버튼으로 이전달, 다음달 이동하기
✅ 달력의 셀을 클릭하여 날짜 선택하기
✅ 선택된 날짜에 입금/출금 내역을 등록하기
❌ 달력에 총 입금, 출금 표시하기
✅ 달력 밑에 선택된 날짜의 내역을 전부 출력하기

월별 상세 화면
❌ 현재 이동한 달의 총 입금, 출금의 퍼센티지를 파이차트에 그리기
👀 현재 이동한 달의 총 내역을 일별로 구분하여 전부 출력하기
❌ 해당 화면에서도 달의 이동이 가능해야 함
❌ 홈 화면으로 돌아갈 버튼이 있어야 하고 이동한 달이 그대로 유지되어야 함

백엔드
✅ 내역 등록하기 API 만들기
✅ 일별 내역 조회하기 API 만들기
✅ 월별 내역 조회하기 API 만들기

Review

달력 그리기
최대한 함수형으로 작성하려고 노력을 하다보니 달력을 그리기 위한 단계가 꽤나 명확하게 되었다.

사진의 함수가 달력을 그리는 함수이다.
getDatesForDraw는 달력을 그리기 위한 2차원 배열로 해당 월의 날짜들을 재구성하여 만든 배열이다.
예를 들어 달력의 첫주에 빈 날짜들 또한 그려내야 하는데 이 빈 값들 또한 그려내기 위해 일부러 빈 객체를 넣어서 7 * weeks 크기의 그리기 전용 배열을 만들었다.

생성된 2차원 배열을 map을 통해서 사진의 템플릿으로 값을 변환 시켜준다.
이렇게 map으로 변환된 템플릿 배열을 join하고 innerHTML에 넣어주면 달력을 그릴 수 있게된다.

달력 클릭 이벤트
처음에는 td 태그 하나하나 전부 이벤트 리스너를 달아 주었다.
그리고 나서 피드백을 받았는데 Web API에서의 이벤트 위임에 대해서 알게 되었고, 칸 하나하나 전부 달아주는 방법또한 물론 가능은 하겠지만 이 경우엔 달력 전체에 이벤트를 달아주고 이벤트 위임으로 인한 이벤트 타겟을 사용하여 td태그에 이벤트를 감지할 수 있게 구현하였다.

remove를 해주는 이유는 달력이 체인지 될때 클릭 이벤트를 안지워 놓으면 계속 겹쳐서 클릭 이벤트가 발생한다.

사진에서 onCalendarClick을 따로 빼주어 이벤트를 등록해주었는데 단순히 함수화를 하기 위한 목적 뿐 아니라 addEventListener 와 removeEventListener의 이벤트 주소가 완전히 동일해야한다.

즉, 익명함수로 똑같은 내용을 작성했다고 쳐도 둘을 다른 함수로 인식하여 이벤트를 지울 수 없기 때문에 따로 빼주게 되었다.

전역 데이터 관리

저렇게 로컬스토리지를 통해서 관리를 했으나 별로 유용하지 못하다는 점을 깨달았다.
currentDate는 현재 이동한 달력의 정보를 담기 위함이었고, selectedDate는 선택된 날짜를 여기저기서 사용하기 위함이었다.
전역 데이터에 대한 나의 정확한 니즈는
"해당 데이터들은 어디서든 사용할 수 있어야 하고 저 데이터 들이 변경될때 달력이 아닌 외부의 요소 (등록하기 헤더, 내역 리스트)들의 내용이 업데이트 되어야 한다."

지금의 방법으로는 그냥 전역 상태의 데이터를 저장하고 각 컴포넌트에서 끌어다가 쓰는 방법 밖에 안된다.
그러다 보니 다음과 같은 의존성을 부여하게 되어 치명적인 문제가 생긴다.

위에서 똑같이 올렸던 onCalendarClick 함수이다.

사진 처럼 캘린더 셀이 클릭되면 저렇게 바로 업데이트가 되어야 한다.
위에서도 설명했다시피 상단 등록하기 해더와 내역 리스트는 각각 캘린더와 별개의 컴포넌트이다.

즉, 코드에서 updateSelectedDateOfHeader, updateAccountList는 각각의 파일에서 import해온 함수들이다.
이것을 두고 의존성이 부여되었다고 한다.
이런 코드를 작성하게 되면 규모가 더 커졌을때 스파게티 코드가 작성될 가능성이 농후하다.
하지만 해결 방법을 몰라 안된다는 걸 알면서도 작성했다.

해결 책으로는 Observer Pattern을 사용하는 방법이 있다.
나도 아직 공부가 더 필요하고 실제로 활용해 봐야하는 패턴이지만
간략하게 설명을 하자면 관리하고 싶었던 전역 데이터를 클래스에서 관리를 함과 동시에 해당 클래스에서 이 데이터들이 변경 되었을시에 실행시켜야할 함수들 또한 저장시켜놓는다.
그리고 set함수를 통해서 이 데이터들을 변경할때 등록했던 함수들까지 실행시키도록 코드를 작성한다.

DBMS 추상화
보통 현업에서 백엔드 개발자들이 mongoDB 같은 가벼운 DBMS로 프로젝트를 만들고 MySQL 같은 DBMS로 변경하는 일이 잦다고 한다.

이렇게 듣고나면 개발 공수가 엄청 올라가는 것 아닌가 생각할 수 있지만 DBMS를 추상화 시켜놓음으로써 하나의 파일만 변경하면 되게끔 세팅해놓을 수 있다.

추상화란 다름이 아니라 DBMS를 사용하기 위해 나만의 인터페이스를 만들어 놓는 과정이다.


이번 프로젝트에서 나는 db를 저렇게 만들어놓고 바로 export해준 것을 볼 수 있는데 이렇게만 만든게 이제 위에서 말한것처럼 추후에 DBMS가 바뀌었을때 개발 공수가 올라가게 된다.

예를 들면 내가 사용한 nedb의 데이터를 조회하는 함수는
db.find(검색할 객체, 콜백 함수) 이렇게 생겼는데 mongoDB에서는 비슷하지만 부분 조회하는 방식이 다르고 MySQL의 경우엔 아예 SQL을 사용해서 조회를 하니깐 방식이 완전 달라질 것이다.

이것을 예를들어 select라는 함수를 따로 저 파일에 만들어서 해당 DBMS의 조회함수를 거기다 넣고 return하는 값은 어쨌든 동일하게 구성한다면
DBMS가 아무리 바뀌어도 해당 파일만 조작하면 유지보수가 상당히 간편해짐을 알 수 있다.

미완이지만 후기

원하던 기능을 전부 개발하진 못했지만 그래도 작은 프로젝트 안에서 많은 문제점을 발견했고 개선 방법을 알게 되었다.
위에 적은 사항들 말고도 HTML과 CSS의 구조, 선택자 관리라던가 HTML dataset 활용등 사소하게 깨달은 내용들이 더 있지만 글은 여기까지 작성하고 마치도록 하겠다.

추후 계획하게 된 미니프로젝트가 있지만 일단은 자바스크립트와 웹 브라우저에 대해서 좀 더 공부하기로 했다.

profile
Software Engineer (전산쟁이)

0개의 댓글