좋은 코드를 작성하는 방법을 찾기 위한 여정
나는 항상 좋은 코드를 작성하는 것에 대한 열망이 있었다. 왜냐하면 그것이 내가 개발자로서의 가치를 높이는 방법의 하나라고 생각했기 때문이다.
내가 프로그래밍을 시작하게 된 계기는 스타크래프트 유즈맵을 만들기 시작하면서이다. 초등학교 5학년 때 처음 접하고 고등학생 때까지 계속했다.
스타크래프트 유즈맵 제작에는 여러 가지 제한이 많았다. 유닛 인식은 항상 왼쪽부터 한다든지, 동시성을 지원하는 타이머가 없다든지 지금은 기억이 잘 나지 않지만, 상당히 많았던 것으로 기억한다. 하지만 이런 제약 속에서도 맵을 만드는 사람들은 온갖 해키한 방식을 이용해서 창의적인 맵들을 만들었다.
한가지 예로 동시성을 지원하는 타이머가 따로 없어, 테란 건물이 일정 체력 이하일 때 불이 붙고 일정 시간마다 체력을 잃는 점에 착안해 1초당 불타고 있는 건물이 잃는 체력 * 원하는 타이머 시간을 건물의 체력으로 설정하고 건물이 터질 때를 조건으로 삼아 타이머로 사용하였다.
이런 방식으로 프로그래밍을 접했다 보니 처음 진짜 프로그래밍을 접했을 때 남들보다 어떻게든 동작을 구현해내는 능력은 조금 뛰어났었다.
하지만, 학교를 졸업하고 개발자가 되어보니 개발을 업으로 삼고 있는, 여기 남은 사람들은 그냥 기본적으로 다들 할 줄 아는 것이더라 더군다나 어떻게든 동작만 우선하기 위해 해키한 방식을 쓰는 것은 실제로 프로그래밍에서는 안티패턴인 경우가 많더라
그때부터 내가 가진 능력이 그렇게 돋보이는 능력은 아니라고 생각하게 됐고 좋은 코드를 작성하기 위해 여러 가지 시도를 많이 해왔다.
좋은 코드란 무엇일까?
좋은 코드를 작성하기 위해서는 무엇이 좋은 코드인지 아는 것부터가 중요하다고 생각했다.
효과적으로 작동, 가독성, 유지보수성, 확장성, 모범 사례, 이해하고 수정하기 쉬우며, 구조가 잘 잡혀있고… SOLID 원칙이 어쩌고저쩌고…
공부를 잘하기 위해서는 충분한 수면 시간을 확보하고, 복습을 중요시하고….
건강해지기 위해서는 운동을 꾸준히 하고, 영양학적으로 균형잡힌 식사를 하고..
알겠는데, 그래서 내가 작업하는 프로젝트, 내 코드에서는 어떻게 하냐고…
많은 시도를 해봤지만, 여전히 코드에서 나는 악취를 지워낼 수가 없었다.
내가 작성한 코드를 1~2주 지나서 다시 보면 밀어버리고 새로 작성하고 싶은 느낌을 계속해서 받았다.
그러던 중 함수형 프로그래밍을 접하게 되었는데
처음에는 map
, filter
, reduce
같은 것이 선언형이라는 건데 이걸 쓰면 함수형 프로그래밍이라고 하더라
잘 이해가 되지 않았다. 그래서 선언적이라는 게 뭔데? 이게 추상화랑 뭐가 다른데?
결국 사용자가 내부를 신경 쓸 필요 없고 함수명을 잘 지어놓은 것 아냐?
그래도 요즘 이게 트렌드라니까 계속해서 관심은 두고 있었다.
다음번에 접했을 때는 순수함수에 대해 알게 되었다.
부작용(side effect)이라는 게 없어야 한다고 한다. 항상 같은 결과를 보장하는 뭐 그런 건데 그게 중요하다고 한다.
키워드를 가지고 더 알아보니 수학적인 내용이라든지… for 문 대신 재귀를 사용한다든지…
이것도 당장 내 코드에 적용하기에는 잘 모르겠더라
그 다음번엔 함수형을 실제로 업무에 사용하기 위해서는 함수의 합성이라는 게 중요하다는 정보를 얻게 되었다.
두 개의 함수 A, B가 있을 때 A의 반환 값과 B의 매개변수가 같을 때 합성이 가능하다고 하더라
정보를 얻고 나서, 내 나름대로 이걸 내 코드에 적용해보려고 함수에서 매개변수로 만들 수 있는 부분은 매개변수로 만들고, 반환할 수 있는 값들은 내부에서 외부의 값을 변경하지 않고 반환해주는 식으로 고쳐봤다.
합성이라는 게 어떤 것인지 아직 다 알아보진 않았지만 A(B(C()))
같은 형태가 되긴 했는데 이것도 좋은 코드인가? 아직 덜 배워서 느낌은 오지 않았다.
그러다가 만들어 놓은 함수들을 보니 순수 함수의 형태를 가지고 있었다.
함수를 합성시켜보려고 함수들을 최대한 순수 함수로 만들다 보니 자연스레 side effect는 한곳으로 몰리게 되고
이때 조금 감이 잡히기 시작했다.
지금까지 배워왔던 것들이 차례차례 연결되기 시작했다.
단일 책임 원칙, 의존성 주입, 스토리북을 사용하는 이유, 테스트를 작성하기 좋은 코드, 불변성, 리액트에서 side effect를 다루기 좋은 위치, 선언형 프로그래밍 등…
그렇게 드디어 1~2주 후에 다시 봐도 최소한 밀어버리고 싶은 충동은 들지 않는 코드를 작성할 수 있게 되었다.
함수를 순수하게, 원자적으로 만들고 순수한 함수들을 조립해서 작성해나갔으니 그럴 수밖에
이제서야 마음 놓고 작성할 수 있는 나에게 맞는 방법론을 찾게 되었지만, 아직도 코드에서 냄새가 날 때가 있다.
기능이나 모듈 하나하나가 아니라 그것들이 결합할 때, 설계에서 냄새가 나는 것 같다…
아직 여정은 한참 남은 것 같다.