우리 모두는 대충 짠 프로그램이 돌아간다는 사실에 안도감을 느끼며 그래도 안 돌아가는 프로그램보다 돌아가는 쓰레기가 좋다고 스스로를 위로한다.
평소처럼 엔터키를 딱 눌렀는데, 뭔가가 다릅니다. 빌드 성공했다는 초록색 알림 대신, 빨간색 얼럿이 슬랙에 쭈루룩... 쏟아지고, 메일 알림 소리가 띵 띵 띵 울리는 게 아무래도 JWT됐습니다.
제가 말하는 자책이라는 것은 자기만 탓하는 것을 말합니다. 이러한 규모의 장애는 혼자만의 잘못으로 절대 일어나지 않습니다. 모든 장애는 보통 부주의가 직접적인 원인이긴 하지만, 대부분의 부주의는 CI/CD와 리뷰 등의 절차를 통해 걸러집니다. 그렇다면 큰 규모의 장애를 일으킨 부주의는 곧 현재의 시스템으로 걸러지지 못한 부주의가 있다는 것을 의미하는 것입니다. 그러므로 해당 장애의 책임은 본인에게만 있지 않습니다. 팀 전체에 있지요.
이 곡선에 개발자의 취업을 대입해보면 아래와 같다.
- 멋모르고 개발자 되겠다고 다짐할 때만 해도 뭐 하나 배울 때마다 재밌고 내가 재능있는 것 같고 드디어 내 운명을 만난 것 같고 신난다.
- 그래서 개발자 해야지~ 하고 취업 시장에 진입하면 잔뜩 얻어맞고 나서 스스로가 얼마나 병신이었는지 깨닫는다.
- 스스로 병신임을 인정하고 그럼에도 불구하고 개발자가 되고 싶은 의지가 남은 사람만이 살아남아 병신을 벗어나려 발버둥치다 보면 어느순간 취업이 된다.
- 스스로의 행운에 감사해하며 진부한 패턴의 글을 남긴다.
그래도 계속 도전하다 보면 나한테 맞는 기회가 온다. 마침 코테 난이도가 원만해서 면접 가고, 면접도 그닥 잘 보지 못했지만 뽑아준 노랑 회사(카xx)에서 인턴을 했다. 잔뜩 희망회로 돌리다가 결국 전환이 안 됐을 땐 세상이 무너진 듯 했다.
하지만 그 과정에서 배운 지식 덕분인지 다음 기회를 잡는 건 훨씬 쉽게 느껴졌다. 그렇게 어느새 취업이 됐다.
즉, 회사라는 이익 집단에는 그냥 프로그래밍만 잘 하는 사람보다는 프로그래밍을 이용해서 유저를 만족시킬 수 있고, 이에 따라오는 매출을 만들어 낼 수 있는 사람이 필요하다는 것이다.
그렇기 때문에 많은 조직들이 좋은 장인들을 채용하기 위해 프로그래밍 스킬 외에도 원활한 제품 개발을 위해 필요한 이해관계자들과의 원활한 협업, 리더십, 비즈니스 인사이트, 유저 경험에 대한 이해 등 다양한 스킬을 요구하고 있는 것이다.
개발자들은 경험적으로 지금 설계를 개판으로 해놓으면 그 부채가 언젠가 부메랑이 되어 반드시 돌아온다는 것을 알고 있다. 그 대표적인 예시가 개발자들 사이에서 흔한 밈으로 구사되고 있는 “레거시 코드”이다. 프로그램의 흐름을 알아보기 힘들고 가독성이 떨어지는 코드는 잠재적으로 수많은 버그의 가능성을 품고 있다.
이렇게 한번 설계가 어긋나게 되면 작은 것 하나만 건드려도 예상하기 어려운 곳에서 버그가 발생하는 상황이 잦아지기 때문에 개발자는 더 신중해질 수 밖에 없고, 조직의 제품 개발 속도도 점점 느려진다. 심지어 나중에는 제품에 새로운 기능을 붙히고 싶어도 설계 때문에 정말로 불가능한 경우까지도 발생할 수 있다.
결국 개발자들이 좋은 설계를 하려는 이유는 제품의 코드 퀄리티를 높혀 빠른 개발 속도를 유지하고 예상하기 힘든 버그를 예방하기 위해서이다. 하지만 앞서 이야기했듯이 좋은 장인은 단지 프로그래밍만 바라보는 것이 아니라 비즈니스까지 포괄하는 넓은 시야를 가질 수 있어야 한다.
좋은 설계를 하는 것은 유저의 좋은 경험을 위한 것이다
사실 필자가 이야기하려고 하는 좋은 설계라는 것은 단순히 중복되는 로직을 추상화하여 분리하거나 변경과 확장이 용이한 패턴을 사용하는 것이 아니다. 상황에 따라서는 기존에 존재하는 코드를 그냥 복붙하는 것이 좋은 설계일 수도 있으며, 매우 급박한 상황이라면 설계고 자시고 일단 작동만 가능하게 만들어서 배포하는 것이 좋은 설계일 수도 있다.
사실 어플리케이션을 설계할 때 가장 선행되어야 할 고민은 바로 “이게 정말 설계를 고민할만한 가치가 있는가”이다.
개발자가 아무리 나중을 생각하고 좋은 설계를 한다고 해도 당장 다음 달에 회사가 돈이 없어서 망한다면 결국은 사라지는 코드들이다. 결국 개발자가 회사라는 조직에 소속되어 프로그래밍을 하고 있는 이상 개발자가 생산한 산출물의 목숨줄도 결국 회사 통장의 잔고에 달려있다는 것이다.
(A/B 테스트는) 둘 중에 하나는 결국 지워야한다. 이런 경우에는 추상화고 나발이고 그냥 같은 페이지를 똑같이 한 벌 복사해서 A/B 테스트 변수에 따라 /test-page/a나 /test-page/b로 랜딩되도록 만들고, A/B 테스트 후 결과가 나오면 그냥 테스트에서 진 페이지 하나를 깔끔하게 날려버리는 것이 오히려 더 좋은 설계일 수도 있다는 것이다.
만약 이런 비즈니스 상황들을 고려하지 않고 프로그래밍만 바라보는 좁은 시야로 개발을 한다면 아무리 설계를 잘 했다고 해도 오버엔지니어링이라는 피드백만 받는 눈물나는 상황이 발생할 수도 있다.