Project

블록 코딩 서비스 회고

J3SUNG 2024. 5. 28. 04:30
728x90

작업 기간
2024.01.05 ~ 2024.02.20


팀원 구성
1인 개발


기술스택
Typescript, HTML, CSS, git, jira, wiki (라이브러리, 프레임워크 사용 X)


후기
처음으로 라이브러리와 프레임워크를 사용하지 않고 개발을 해보았는데, 어려움이 많았습니다. 어떤 구조로 개발을 진행할 것인지, 렌더링과 상태관리는 어떻게 진행할 것인지 고민하였습니다. React와 비슷한 구조로 진행하였으나, 부족한 부분들이 많았던것 같습니다.
요구사항을 만족하는 것을 우선적으로 개발을 진행하였으며, 모든 요구사항을 구현하였습니다. 하지만 설계에 시간을 더 사용해서 확장성과 재사용성이 높은 구조로 개발하였어야 한다고 생각합니다.
애자일 방식으로 개발을 진행하였으며, 꾸준히 리팩토링을 진행하였습니다. 설계에서 부족한 점으로 리팩토링 시간이 길어지고, 개발 후반에 발생한 설계문제는 고치는 비용이 높아진다는 것을 깨닫게 되었습니다.
코드리뷰와 대면리뷰를 통해서 코드를 개선하고 협업하기 위한 코드를 작성하기 위해 노력하게 되었습니다.


주요 기능
- 구조

컴포넌트 기반으로 개발되었습니다. 그리고 상태 관리와 렌더링을 위한 API를 만들었습니다. 이벤트가 발생하면, 상태가 변경되고, 렌더링이 됩니다.

- 블록 구현
블록 데이터 객체는 여러 블럭 객체가 합쳐져 있는 형태로 존재합니다. 각각의 블럭들은 해당하는 타입의 블럭들을 만들어내고, 연결됩니다.
각 블럭객체는 클래스로 이루어져있고, 상속과 오버라이딩을 해서 타입에 맞는 블럭의 역할을 수행합니다. 블럭의 이동, 추가, 삭제, 연결 등의 작업이 일어날때, 블럭 데이터 객체를 수정하게 되고, 이는 상태변경이 발생합니다. 상태 변경이 일어날 경우 렌더링이 발생하여, 변경된 상태를 기반으로 블럭들을 새롭게 그리는 과정을 진행합니다.

- 블록 종류
선언문(시작, 함수)
일반문(변수, 출력, 타이머, 함수실행, 디버깅)
제어문(조건문, 반복문)
표현식(값, 입력, 변수참조, 수식연산, 문자열, 랜덤값, 함수호출, 논리연산, 비교연산, 부정연산)

- 블록 연결 및 배치
각 블록의 위치좌표가 지정되어있으며, 다른 블록들의 내부로 들어갈 경우, 상위 블록의 위치에 따라 위치가 지정됩니다.
다른 블록과 연결 될 때, 상위블록의 객체에 자식블록의 객체가 포함되며, 이렇게 변경 되었을 때, 변경 된 블록 객체를 기반으로 다시 렌더링하여 사용자에게 보여줍니다.

- 프로그램 실행 제어
프로그램 실행 과정은 트리 구조로 연결된 블럭 객체들을 순회하면서 인터프리터처럼 각 블럭의 실행 메서드를 호출하는 방식으로 진행됩니다. 이때, 각 블럭은 실행 결과를 반환하고, 이러한 결과들은 후속 블럭의 실행 로직에 활용됩니다. 각 블럭이 실행하기 전에 현재 프로그램상태와 에러발생여부를 확인하여서 중지 버튼을 누를 경우, 순회를 멈춰서 실행을 정지하게 됩니다. 또한, 일시정지버튼을 누르면 프로그램 상태 변경에 대한 커스텀 이벤트를 등록하여, 프로그램 상태가 변경되면 다시 진행되거나 종료되도록 구현하였습니다.

- 프로그램 실행 예외 처리
프로그램 동작 과정에서 다양한 예외 처리를 구현했습니다. 주요 처리 대상은 무한 루프, NaN, infinity, nullPointer입니다. 무한 루프 감지는 사용자 입력 대기 시간과 타이머 작동 시간을 제외하고 10초 이상 지속될 경우 발생하도록 설정했습니다. 이 방식은 특정 작업이 10초 이상 걸릴 수 있는 사용자의 기대를 고려하여, 사용자와의 상호작용을 통해 예외를 판단하는 방향으로 개선할 계획입니다. NaN과 infinity에 대해서는 해당 값들이 계산 결과로 나타날 경우 예외를 발생시키도록 처리했습니다. nullPointer 예외는 변수나 함수가 존재하지 않을 때 호출하려고 할 때 발생합니다. 

- URL 블록 공유
URL을 통해 객체 데이터를 공유하는 기능을 구현했습니다. URL에 포함될 수 있는 데이터의 양에는 제한이 있기 때문에, 데이터의 크기를 최대한 줄이는 것이 목표였습니다. 이를 위해 사용되는 key 값을 짧은 문자로 치환하고, name, type과 같이 반복적으로 사용되는 값들도 짧은 문자로 대체했습니다. 또한, 각 블럭의 ID를 제거함으로써 데이터 크기를 37% 줄일 수 있었습니다. 추가로, compressionStream API를 사용하여 최종적으로 데이터 크기를 91%까지 줄이는 성과를 달성했습니다. 이러한 최적화를 통해 URL을 통한 데이터 공유의 효율성을 크게 개선할 수 있었습니다.

- Javascript 코드 export
JS Export 기능은 블록으로 구성된 로직을 JavaScript 코드로 변환하는 과정입니다. 이 과정에서 트리 구조의 객체를 순회하여 각 블록의 역할에 맞는 JavaScript 코드를 생성하고, 이들을 결합해 최종적으로 하나의 JavaScript 코드를 형성합니다. 블록코딩에서 문자와 숫자, 변수와 값의 구분이 명확하지 않기 때문에, 이를 코드 변환 시 명확히 구분해주어야 했습니다. 예를 들어, 숫자는 따옴표를 제거하고 문자에는 따옴표를 추가했습니다. 또한, 변수나 함수 참조 시에는 따옴표를 제거했습니다.

- JSON 저장 / 불러오기
블록 객체를 json파일로 내보내고 불러오는 기능입니다.

- 디버깅 블록 구현
디버깅 블록 기능을 통해, 사용자는 특정 블록에 시간을 지정할 수 있으며, 이를 통해 지정된 시간 동안 해당 블록과 이후의 블록들이 실행되는 동안 하이라이트 효과가 적용됩니다. 이를 통해 사용자는 현재 실행 중인 블록을 시각적으로 확인하고, 출력 결과가 예상대로 순차적으로 나타나는지 검증할 수 있습니다.

- 복사 기능
cmd를 누른채로 드래그를 할 경우, 복사가 됩니다. 드래그하는 블록 객체를 그대로 복사하고, 해당 블록들의 ID값만 변경해주었습니다.

- 되돌리기 기능
이전 블록 상태를 기억하는 스택을 구현하고, 이벤트가 발생할 때마다, 스택에 이전 상태를 넣습니다. 컨트롤 + z, cmd + z가 입력되었을 때, 이전 상태로 돌아갑니다. 


배운점
1. 코드개선
- 코드리뷰와 대면리뷰를 통해서 코드를 개선 할 수 있었습니다. 협업하기 위한 코드를 작성하기 위해서 노력하게 되었습니다.

2. 학습방법
- 새로운 기술과 정보에 대해서 학습하는 방법을 익히고, 해당 기술을 적용할 때 더 좋은 방법은 없는지, 현재 프로젝트에 적합한지 등을 고민하는 습관을 가지게 되었습니다.


아쉬운점
1. 기획 설계의 부족
- 기획과 설계에서  부족한 부분이 있어서 잦은 리팩토링이 발생하였습니다. 또한 문제를 고치는 시점이 늦어질수록 고치는 비용이 커진다는 점도 알게되었습니다.

2. 기록
- 어려웠던 부분과 배운 점들에 대해서 상세하게 기록해두지 못했던 부분이 현재에 아쉬운 부분으로 남아있습니다.