
객체지향 프로그래밍을 잘 지키자
프리코스 지원서를 쓰면서 프리코스에서 얻어가고자 하는 목표를 세웠다. 그 중에 하나가 객체지향 프로그래밍을 잘 지키는 것이다. 몇 달 전부터 JS deep dive 라는 책을 읽기 시작했는데 사실 이 책을 읽기 전까지는 프론트엔드 개발자와 객체지향 패러다임은 그닥 연관이 없다고 생각했었다.
아직 1/3정도 밖에 보지 못했지만 JS가 함수형 패러다임과 객체지향 패러다임이 어우러진 멀티 패러다임 언어임을 알게되었다. 프리코스를 준비하며 어떻게 하면 객체지향 프로그래밍을 잘 지킬 수 있을 지에 대해 고민했다.
객체 지향 프로그래밍의 특징은 추상화, 상속, 다형성, 캡슐화인데 각각의 개념에 대해 알고 있지만 이를 적용하는 것은 어려웠다. 결론적으로 이러한 특징들 즉, 객체지향 프로그래밍을 잘 지키기 위한 방법 중 하나는 한 함수가 한 가지 일만 하도록 하는 것임을 알게 되었다.
그렇게 한 함수가 한 가지 일만 하는지 점검하는 것을 프리코스에서의 학습 계획 중 일부로 세웠다.
공유하는 프로그래머가 되자
누군가에게 내 코드를 보여주는 것은 사실 아직 좀 꺼리게 된다. 분야 특성상 타인과 같이 일하는 경우가 많고 서로의 코드를 보게되는 경우 또한 많다는 것은 알고있다. 하지만 내 코드가 잘 짜여진 코드가 아니라고 생각이 들면 남에게 보여주는 것을 망설이게 되는 것 같다.
이는 개발자로서 좋지 않은 마음가짐이라고 생각했고 프리코스 동안 내 코드와 생각을 망설임 없이 타인과 공유해야 겠다고 다짐했다. 또한, 내 코드만 보여주는게 아니라 타인의 코드를 보면서 의견을 주고 받는 연습하고자 했다.
첫 번째, 혼자서 충분한 시간을 들여 하나의 함수가 하나의 일만 하는지 점검해 볼 것 입니다.
두 번째, 최소한 3인 이상의 사람과 서로 작성한 코드와 가지고 있는 생각을 공유합니다.
세 번째, 이전의 두 가지 과정을 거쳐 수정된 사항에 대해 정리하며 회고를 진행하려고 합니다.
먼저 1주차 미션인 문자열 덧셈 계산기 기능 요구 사항은 이렇다.
기능 요구사항을 보면 간단해 보인다.
입력한 문자열에서 숫자를 추출하여 더하는 계산기를 구현한다.
Error를 발생시킨 후 애플리케이션은 종료되어야 한다.결과 : 6
덧셈할 문자열을 입력해 주세요.
1,2:3
결과 : 6
사실 구현 목록을 적을 때까지도 생각보다 단순하다고 생각했다.

구현을 하면서 뭔가 생각보다 굉장히 복잡하다는 생각이 들었지만 우선 구현을 마친 이후에 문제를 다시 읽게되었다. 문제를 천천히 읽어보니 내가 놓친 부분이 있다는 것을 깨닫게 되었고 때문에 문제를 더 어렵게 풀었다는 것 또한 알게되었다.
기능 요구사항을 보면 "커스텀 구분자는 문자열 앞부분의" 라고 쓰여있다. 나는 앞 부분이라는 말을 놓쳐서 커스텀 구분자 등록 로직이 앞부분이 아닌 어디서든지 다 나올 수 있다고 생각해 구현을 했고 결국 오버?하게 일부 비효율적으로 구현하게 되었다.
심지어 여러자리 숫자가 올 수 있는데 이를 고려하지 못하고 한 자리 수만 처리가능 하도록 구현했다.
지금까지 기능 구현 목록에 많은 시간을 쏟아본 적이 없었는데 이때 요구사항을 분석하는 것이 정말 중요하다는 것을 깨달았다....

그렇게 전반적인 로직을 뜯어 고쳤다.


이어서 리팩토링도 진행했다.
디스코드 커뮤니티를 이용해 세 분의 코드를 리뷰했지만 내 코드는 두 분에게 밖에 리뷰받지 못했다. 한 분은 중복되는 에러처리를 지적해주셨고 다른 한 분은 같은 로직이지만 더 간단한 코드를 제시해주셨다.
다른 분들 코드를 리뷰하며 느낀점은 간단한 코드를 구현함에도 코드는 정말 다양한 것이 신기했다. 어떤 분들은 MVC 패턴으로 구현했고 클래스를 전부 분리하신 분도 있었고 에러처리에 엄청 신경쓰신 분도 있었다.
특히, 에러처리를 꼼꼼히 하신 것을 보고 나도 프리코스 다음 주차에 에러처리에 힘을 더 실어보기로 결정했다.
이번 주차에는 원래 계획했던 것만큼 활발히 코드와 생각을 공유하지 못한게 아쉽다.
다음 주차에 가장 많이 신경 쓸 것은 다른 사람과 소통하는 것이다.
기능 구현 목록 작성에는 적당한 시간을 쏟아야 한다.
지금까지의 과제, 프로젝트에서 개발하기 전에 기능 구현 목록을 작성해 본 경험이 없었습니다. 이번에 처음으로 구현해야 할 기능에 대해 생각해 보고 정의한 후 개발을 진행했습니다. 확실히 무작정 개발을 시작하는 것보다 진행 속도가 빨랐습니다.
다만, 어느 정도 시간을 할애해야 하는지 정하는 것이 어려웠다고 생각합니다. 기능을 구현하며 어떤 에러처리를 해야 하는지 생각하다 보니 개발을 시작하는 데 시간이 너무 많이 소모되었습니다. 그리고 개발 시작 전에 많이 고민했다고 생각했지만 개발을 진행하니 처음 설계했던 것에 오류가 있어 다른 방향으로 설계를 바꾸었습니다.
(구분자와 자연수를 한 번에 분류하는 설계 => 구분자 먼저 분류 후 자연수를 분류하는 설계)
개발하기 전에 어떤 기능을 구현할 것인지 생각하는 것은 필요하지만 너무 많은 시간을 할애할 필요가 없다는 것을 몸소 깨닫게 되었습니다.
생성형 AI를 사용하지 않는 개발
이번 우테코 코딩테스트에서는 생성형 AI를 사용할 수 없습니다. 때문에 프리코스 기간에 과제를 수행하면서 생성형 AI를 사용하지 않는 것을 계획했습니다. 저는 평소 알고리즘 문제나 과제를 할 때 해결이 안 되는 부분을 만나면 생성형 AI를 활용해 학습했었습니다. 이렇게 개발이 원활히 진행되지 않을 때 생성형 AI를 이용하면 한, 두 가지 정도의 방법만 알고 넘어갔었습니다.
하지만 구글링을 통해 방법을 찾고 계속 고민하니 계속해서 다른 방법들을 찾을 수 있었고 평소 무심코 사용한 생성형 AI가 제 사고의 폭을 줄이고 있음을 깨닫게 되었습니다.
(커스텀 구분자를 찾을 때 구현할 수 있는 방법들)
제가 계획했던 프리코스에서의 학습 계획과 점검 방법입니다.
첫 번째, 혼자서 충분한 시간을 들여 하나의 함수가 하나의 일만 하는지 점검해 볼 것입니다.
기능 구현을 마친 이후에 findAndRemoveCustomDelimiters 함수와 splitAndAddNumbers 함수가 각각 두 가지 일을 하고 있다고 생각했습니다.
두 가지 일을 하고 있었지만 무작정 분리하는 것이 아닌 분리해야 하는 이유를 생각하며 진행했습니다.
a. findAndRemoveCustomDelimiters
이 함수는 두 가지 일을 하고 있지만 커스텀 구분자를 찾고 제거한다는 연속적인 일을 하고 있습니다.
재사용성 측면에서 이 두 가지 기능을 분리하더라도 연속된 일을 하기 때문에 장점이라고 생각하지 않았습니다. 다만 가독성 측면에서는 각각을 분리하는 것이 좋다고 생각해 리팩토링을 진행했습니다.
이러한 이유로 두 기능을 분리는 하되 find 기능 안에 remove 기능을 구현했습니다.
b. splitAndAddNumbers
처음에는 split가 비교적 간단한 작업이라서 문자열에 push하는 기능과 함께 구현했습니다.
하지만 간단한 작업이더라도 split과 push 기능을 하나의 함수에 구현하는 것은 가독성, 재사용성 측면에서 모두 좋지 못하다고 생각해 리팩토링했습니다.