프로젝트 설명
자판기 상품, 동전 관리와 상품 구매할 수 있는 프로그램입니다.
프로젝트 목적
- 대외활동에서 수행했던 프로젝트였습니다. 당시에는 조건에 맞춰 구현하기 바빴지만, 끝난 후에 배웠던 점을 바탕으로 다시 구현하면서 Vanilla JavaScript 능숙도를 높였습니다.
프로젝트 결과물
구현 기능
- 자판기에 상품 추가, 삭제
- 자판기에 동전 충전
- 동전 투입, 상품구매, 잔돈반환
수행 작업
- 객체지향 컨셉 활용해 UI, 비즈니스 로직 분리한 설계
- 이벤트 위임 패턴을 적용해 이벤트 처리 최적화
- Class 상속개념 활용해 Component Base 구현
- setState 일괄처리 로직 개발
구현 중 겪었던 문제
유지보수하기 좋은 설계에 대한 고민
고민
- 현재상황: 상품 추가, 삭제, 구매 등 관리해야할 이벤트가 많았고, 이벤트에 의해 상태값이 변할 때 새로고침 없이 반영되도록 처리해야했음.
- (이벤트 핸들러 → 상태값 변경 → UI 반영) 위와 같은 흐름을 어떻게 유지보수하기 좋게 관리할 수 있을지 고민.
- 컴포넌트와 비즈니스 로직 역할을 명확히 구분함.
- 컴포넌트 - UI, 이벤트 핸들러 로직 담당
- 비즈니스 로직 - 객체로 관리
문제 비즈니스 로직을 객체 단위로 나누는 기준
해결방법
- 객체지향의 사실과 오해 책을 읽으면서, 객체가 수행하는 행동을 기준으로 유사한 점을 묶어 의미있는 객체 단위로 로직 분리.
- 추가로, 객체와 UI의 의존도를 낮추고자 페이지에서 필요한 객체 주입받아 이용하도록 설계함
배운 점
로직을 객체로 분리해, 객체끼리 소통해 하나의 어플리케이션을 만들어내는 경험을 할 수 있었습니다. 바로 구현하기 보다 필요한 flow, 어떻게 관리할건지 등 큰 그림을 설계하고 구현하는 게 정말 중요하다는 걸 깨달았습니다.
setState 구현하면서 불필요한 렌더링 줄이기 위한 노력
고민
- 수정된 state를 UI에 반영하기위해, setState 실행 시 리렌더링 되도록 구현.
- 문제는, 하나의 이벤트에서 여러 개의 state 변경할 때 state 변경횟수만큼 리렌더링이 발생함.
- 하나의 이벤트가 끝났을 때 setState를 한번에 처리해 불필요한 렌더링 줄이고자 판단.
문제 1. setState 일괄처리 구현 방법
해결방법
- 리액트 hooks도 일괄처리하기때문에 리액트 내부 코드를 찾아봤고, setState에서 queue에 등록시키는 로직을 발견함.
- queue에 등록하고, 쌓인 작업을 처리하는 로직 TaskQueue에 구현함.
문제 2. 이벤트 핸들러 함수가 끝난 시점에 쌓인 작업 처리 함수를 호출하는 방법
해결방법
- 이벤트 핸들러가 끝났을 때 콜스택에서 제거되어 콜스택이 빈다는 점을 활용해서, 이벤트 핸들러 내부에 setTimeout으로 처리함수를 콜백으로 넣어 구현.
배운 점
리액트 setState가 비동기로 작동하는 이유가 궁금했었는데 이를 풀 수 있는 경험이었고, 오픈소스 내부코드 보는 거에 두려움이 사라지고, 큰 도움이 된다는 걸 깨달았습니다.
회고
객체지향 프로그래밍
반복되는 코드를 함수로 작성해 이용했기에 클래스의 필요성을 크게 느끼지 못했는데, 자판기를 구현하면서 상속 개념, 필요한 상태값 관리 등을 이용하는 경험을 통해 객체지향 프로그래밍의 이점을 깨닫게 되었습니다.