소프트웨어 엔지니어링에서의 "좋은 취향"이란 무엇인가?
(seangoedecke.com)- 기술적 취향은 기술적 실력과는 다른 개념으로, 뛰어난 능력이 있어도 취향이 나쁠 수 있고, 능력이 부족해도 취향이 좋을 수 있음
- 소프트웨어 엔지니어의 취향은 프로젝트에 맞는 엔지니어링 가치 선택 능력을 의미함
- 어떤 코드가 보기 좋다/나쁘다, 어떤 설계 결정이 만족스러운가, 어떤 문제에 집착하는가와 같은 감각에서 드러나며, 이는 곧 자신이 중시하는 엔지니어링 가치의 집합을 반영
- 소프트웨어 엔지니어링의 모든 결정은 트레이드오프의 연속이며, 미성숙한 엔지니어는 특정 접근을 절대적 진리로 여기지만 성숙한 엔지니어는 맥락에 따라 유연하게 가치를 조율함
- 좋은 취향은 특정 프로젝트에 맞는 가치들의 우선순위를 선택할 수 있는 능력이며, 나쁜 취향은 "베스트 프랙티스" 같은 절대적 기준에 집착하는 경직성에서 나타남
- 취향은 다양한 프로젝트 경험과 개방적 사고를 통해 쌓이며, 결국 프로젝트 성공 여부를 통해 좋은 취향의 유무가 드러남
기술적 취향과 실력의 차이
- 기술적 취향은 뛰어난 실력과 반드시 일치하지 않음
- 누구나 요리 실력과 별개로 좋은 음식과 나쁜 음식을 구분할 수 있는 것처럼, 소프트웨어에서도 능력보다 앞서 취향이 형성됨
- 어떤 코드가 "좋아 보이는지" 혹은 "별로인 것처럼 보이는지"에 따라 엔지니어의 취향이 반영됨
- 어떤 설계 결정에 만족을 느끼고, 어떤 문제에 더 신경을 쓰는지는 취향의 일부로 작동함
- 기술적 능력은 반복과 학습으로 성장 가능하지만, 취향은 그보다 모호하고 직관적인 방식으로 발달함
-
엔지니어링 취향의 지표
- "이 코드가 보기 좋다/나쁘다"라고 느끼는 것
- 일부 설계 결정에 대한 강한 만족감 또는 무덤덤함
- 퇴근 후에도 계속 신경 쓰이는 소프트웨어 문제와 그렇지 않은 문제
- 취향이란 현재 프로젝트에 맞는 엔지니어링 가치를 채택하는 능력이라고 생각함
실력과 취향의 구분
- "좋아 보이는 코드"가 실제로 더 좋은 코드여야만 할까하는 의문이 있음
- 예: map/filter를 선호하는 사람은 코드 가독성과 순수 함수를 중시하지만, for 루프를 중시하는 사람은 성능과 단순한 확장을 중시할 수 있음
- 이는 옳고 그름의 문제가 아니라 중시하는 가치의 차이임
- 언어나 컨텍스트에 따라 각각의 장단점이 존재하기 때문에, 어떤 선택이 반드시 더 좋은 것은 아님
- 각 엔지니어가 중요하게 보는 가치가 다르며, 이에 따라 선호가 달라짐
엔지니어링 취향이란 무엇인가
- 소프트웨어 엔지니어링의 거의 모든 결정은 상충하는 가치 간의 균형(트레이드오프) 임
- 미숙한 엔지니어는 자신의 취향에 지나치게 고집을 부림
- 성숙한 엔지니어는 다양한 관점에서 이점을 파악하고, 현재 상황에 맞는 선택을 중시함
- 중요한 것은 X(기술)와 Y(기술) 중 무엇이 더 좋은가가 아니라, 현재 프로젝트에 X의 장점이 Y보다 더 필요한가의 판단임
-
엔지니어링 가치의 예시
- Resiliency: 시스템이 장애나 네트워크 문제에도 잘 동작하는가
- Speed: 이론적 한계에 가까운 성능을 보이는가, 불필요한 작업이 많은가
- Readability: 새로운 엔지니어가 빠르게 이해하고 적응할 수 있는가, 함수가 짧고 명확한가
- Correctness: 잘못된 상태가 모델링되는가, 테스트와 타입, assert 등이 충분한가, 심지어 형식적 검증이 적용되는가
- Flexibility: 시스템 확장이 쉬운가, 변화가 간단하게 적용되는가
- Portability: 특정 환경에 종속적인가, 배포 환경 변화가 간단한가
- Scalability: 10배, 100배 트래픽 증가 시 시스템 확장 또는 자동 스케일링이 가능한가, 병목이 어디에 존재하는가
- Development speed: 시스템 확장이 얼마나 빠른가, 대부분의 엔지니어가 작업 가능한가
- 그 외에도 elegance, modern-ness, 오픈소스 활용, 유지 비용 등 다양한 가치 존재
- 모든 엔지니어가 각 가치에 같은 수준의 관심을 갖지는 않음
- 본인이 어떤 가치를 가장 높게 평가하는지에 따라 사용하는 언어, 프레임워크, 설계 패턴 등이 달라짐
나쁜 취향의 특징
- 나쁜 취향은 본인이 선호하는 가치가 현재 프로젝트에 적합하지 않을 때 발생함
- 특정 기술, 방법론의 장점을 자신의 프로젝트에 일관되게 밀어붙이는 유연성 부족이 문제임
- 항상 "best practice"만을 내세우는 주장에는 상황 맞춤형 판단 결여가 있음
- 유연성 없는 엔지니어는 특정 프로젝트에서는 잘 맞을 수 있으나, 환경 또는 업무 변화 시 심각한 문제를 야기할 수 있음
좋은 취향의 특성
- 좋은 취향은 문제 상황에 따라 올바른 엔지니어링 가치를 잘 선택하는 능력임
- 단순 기술 능력과 달리, 복잡한 실제 프로젝트 맥락에서만 검증 가능함
- 자신이 동의한 설계 결정이 채택된 프로젝트가 잘 진행되면 본인 취향의 적합성을 가늠할 수 있음
- 다양한 프로젝트 경험, 어느 순간에 새로운 가치에 대한 개방적 태도가 중요한 학습 요소임
- 유연성을 유지하고, 특정 기술이나 방법에 대한 고정관념을 피하는 것이 좋은 취향 형성에 도움을 줌
맺음말
- 좋은 취향은 실력만큼이나 중요하며, 성장 과정에서 다양성과 유연성, 그리고 자기 성찰을 통해 개발 가능함
- 몇몇 사람들은 경험 이상으로 뛰어난 취향을 보이기도 함 (프로그래밍 및 타 분야의 영재 등)
추가 논의
- Hacker News 댓글에서는 "취향"의 존재 자체에 회의적인 의견도 있었음
- 일부는 모든 문제에 단 하나의 올바른 해법이 있다고 주장했지만, 저자는 현실에서는 여러 해법이 가능하고, 결국 개인의 가치와 맥락이 선택을 좌우한다고 반박함
- 또 다른 의견으로는 고객과 비즈니스 맥락도 취향의 일부라는 지적이 있었음
취향하면 토발즈의 TED 영상이 생각나네요:
https://www.ted.com/talks/linus_torvalds_the_mind_behind_linux
14:20 부터, linked list의 entry 제거 코드의 구현 방식으로 보는 좋은 취향
해커뉴스 의견에 언급된 "객관적으로 나쁜 결정(예: 리스트에서 O(n) 검색 vs 딕셔너리로 O(1) 검색)" 조차도 맥락에 따라 다르게 결정해야 할 수 있지요.
조회를 단 한번만 하는 경우라면, 리스트에서 O(n) 검색을 하는 것보다 해시 테이블을 만드는 비용이 더 클 수 있으니까요.
Hacker News 의견
-
미성숙한 엔지니어는 자신의 취향에 너무 집착하는 경향을 경험함, 그리고 이런 미성숙함은 경험 많은 엔지니어에게도 있을 수 있음. 예전에 친구들의 컴퓨터 과제 코드를 도와줄 때, 내가 싫어한다는 이유로 코드를 전부 새로 쓰고 싶은 충동을 느꼈음. 하지만 결국 그렇게 하면 시간이 너무 오래 걸리고 친구들이 결과물을 이해하지 못하게 됨을 깨달았음. 그래서 친구들의 접근 방식에 약간의 수정만 더해주는 식으로 도왔고, 그들은 더 만족스러워했음. 이런 경험 덕분에 다양한 시각을 알게 되어 내 코드도 더 발전함. 내가 오히려 친구들에게 고마워해야 한다는 생각이 들었음. 지금도 나는 선입견을 버리기 어렵지만, 가능한 한 상대방의 관점을 진지하게 이해하려고 노력하며, 때론 그 방식이 더 뛰어남을 인정하려 함. 원칙이라는 것은 사실 꽤나 주관적인 것이므로, 항상 원칙에만 기대는 것은 상황을 진지하게 고민하지 않고 그냥 게으른 접근임을 의미함
-
주니어 엔지니어가 비효율적으로 뭔가를 하고 있더라도, 나는 절대 그들이 덜 최적화된 방식을 쓴다고 말하지 않음. 대신, 왜 그렇게 했는지 항상 물어봄. 매 대화가 끝나면 우리 둘 중 누군가는 뭔가를 배움. 내가 새로운 방식이나 그들의 이유를 알게 되거나, 그들이 장기적으로 왜 그 방법이 통하지 않는지 배우게 됨. 어느 쪽이든, 이런 대화는 결코 대립적으로 끝나지 않음
-
"좋은 취향"은 훌륭한 API, 좋은 코드들을 경험하면서 생긴다고 생각함. 좋은 코드는 보면 바로 알아차릴 수 있고, 시간이 지나면 나도 그렇게 쓸 수 있어야 함. 하지만 이 분야에 처음 입문하면 좋은 코딩 취향을 가지기 어렵고, 경험이 있다고 해서 반드시 취향이 생기는 것도 아니라서, 항상 좋은 취향을 찾고, 인식하고, 모방하고자 하는 노력이 필요함
-
선입견, 편견, 경직된 사고방식에서 벗어나는 해결책은 교육과 개개인이 가지고 있는 관점 밖의 다양한 경험을 쌓는 것임. 다른 사람의 시각에서 세상을 이해하려고 적극적으로 노력해야 사람·직업인으로 성장할 수 있고 관점을 넓힐 수 있음. 나처럼 다양한 분야에 관심이 많은 엔지니어는 다른 해결책이나 시각이 있다는 사실만 알아도 내 문제 해결 방식이 달라져 첫 본능적 접근보다 더 나은 해법을 찾게 됨
-
이래서 여러 가지 프로그래밍 언어로 실험해보는 것이 좋음. 항상 지금까지의 관점을 계속 도전하게 하는 새로운 언어에 도전하면서 "아하" 하고 깨닫는 순간이 끊임없이 찾아옴. 처음엔 어색하거나 틀려 보일 수 있지만 그 이유와 방식을 완전히 이해하기 전까진 원래 그렇다고 받아들이는 과정이 필요함
-
멋진 의견임. 이런 사고방식이 내가 직접 채용하거나 같이 일하는 팀원들에게 적용하는 방식임. 목표나 결과가 달성된다면 내 과정, 세부사항까지 반드시 맞출 필요는 없음. 다양한 방식이 있음을 인정함
-
-
패션에서의 "좋은 취향"은 옷 한 벌 한 벌 자체보다, 각기 본질적으로 별 의미 없어 보이는 옷들을 조합해 강력하고 조화로운 느낌을 만들어내는 것이라고 생각함. 이 글이 그런 방향으로 가줄 줄 기대했음. 소프트웨어 엔지니어가 취향으로 결정하는 게 과연 단순 기술적 트레이드오프가 아닌, 진짜 취향의 영역인지 더 탐구하고 싶음. 참고로, 이 글 자체가 취향이 안 좋은 예시처럼 느껴짐. 내용 면에서는 각 파트가 무난하게 잘 쓰여 있지만, 전체적인 "룩"을 만들지 못해서 글이 산만해진 느낌임. 저자에 대한 비방은 아니고, 주제가 훌륭하다고 생각하니 더욱 더 개선 의견을 전하고 싶음
-
옷 한 벌이 자체로 의미 없다는 의견엔 동의하지 않음. 의복은 조합되기 전에도 문화적, 역사적, 상징적 의미가 있음. 패션은 단순 조합 이상의 영역임. 또한 패션에도 생산, 착용, 매칭 등 다양한 트레이드오프가 존재함
-
네가 궁금해 하는 “아름다움과 우아함을 우리는 어떻게 인식하는가”는 고대로부터 철학자들의 주제였고, 단일 기사로 결론내기엔 너무 방대함. 건축 분야의 Christopher Alexander가 이를 깊이 탐구했고, 그의 사상은 소프트웨어 아키텍처에도 큰 영향을 줌. Alexander는 객관적인 아름다움이 있다고 주장했음. 그의 OOPSLA 기조연설이나 Roy Fielding의 박사 논문 참고할 만함. 이 글에서 언급된 “가치”는 Fielding 논문에서는 “아키텍처 속성”으로 더 체계적으로 정리되어 있음
-
재밌게도, 나는 이 글이 주제를 깊이있고 체계적으로 다룬, 흔히 찾기 힘든 보기 드문 명문이라고 생각함
-
엔지니어가 어떤 결합에서 진정 “취향”이 판가름되는 순간, 그리고 단순 기술적 트레이드오프와 구분되는 “취향의 영역”을 묻고 싶어 함. 내가 볼 때 많은 결정을 “기술적 트레이드오프지만 절대적으로 입증하거나, 차이가 미미해 실질적으로 상관 없는 경우”로 치부함. 즉, 따지기 애매할 땐 그냥 취향으로 둠
-
대다수 개발자들은 일반적으로 패션 취향이 부족하고, 그래서 전반적으로 좋은 취향 자체를 잘 이해하지 못한다는 점 있음. 그리고 대부분의 테크 세계의 것들은 비(非)테크인에게는 전혀 멋지거나 쿨하지 않음. 프로그래밍 언어는 멋지지 않음. 개발 세계에서는 시작점조차 “멋있지 않음”부터 시작해서 아래로 내려가는 구조임. 예시로, Rust, C++ 등은 “멋지지 않음” 범주, 생소한 함수형 언어나 Bash, Linux 등은 “정말 멋없음” 카테고리에 들어감
-
-
좋은 취향은 누구나 쉽게 썼을 것 같은 강력히 단순한 코드를 쓰는 것임
-
또다른 예시를 공유함. 72년식 Dodge Challenger를 뜯었다가 조립하면서, 이 차가 단순하고 직접적이며 저렴하게 놀랍게 잘 만든 차라는 점에 항상 놀람. 예를 들어 계기판 전원은 자동차 전체 전압(10~18V)과 별도로 5볼트가 필요한데, 5볼트 이상이면 회로를 끊고, 미만이면 닫는 일종의 버저(전자석 활용)가 있어 빠르게 on/off되어 평균적으로 5볼트를 만듦. 이를 대부분 전자식 전압조절기로 바꾸지만, 그러면 계기판이 안 들어옴. 실제로는 계기판이 기계식이라 5볼트의 미세한 노이즈가 없으면 바늘이 자주 멈추는데, 오히려 이 '거친' 5볼트가 멈춤을 막아줌. 전자식으로 대체하면'노이즈'를 일부러 추가해야 함. 이런 간단한 기계식 장치가 효과와 단순함 면에서 얼마나 뛰어난지 감탄함
-
이런 단순 코드의 진정한 가치는 코드 유지나 작업자의 시간을 절약해줘도, 보통 제대로 인정받지 못함. KISS(Keep It Simple, Stupid) 원칙을 실천한 코드가 오히려 가치가 안 보인다며 폄하받을 때가 많음. 그래서 실제로 필요없는 복잡함을 관리하는 일만 하는 팀/조직이 존재하기도 함
-
가끔 엔지니어가 비범한 걸 할 수 있으면 좋지만, 정말 중요한 건 처음엔 힘들어 보여도 결국엔 평범하고 단순한 해결책을 자주 찾아내는 엔지니어임
-
발레를 보면 “정말 쉬워 보인다!”는 얘기만 들리지만, 실제로 그들이 수만 번을 연습해서 정말 쉽게 해내는 것임
-
복잡한 것을 정말 단순하게 요약해내는 사람을 언제나 가장 존경함. K&R C 예제처럼 명쾌하게, 다만 주석은 조금 더 꼼꼼하게 남겨주길 바람
-
-
"한눈에 코드를 이해하고 신규 엔지니어 온보딩이 쉬운가"라는 질문은 생각보다 쉽지 않음. 신규라는 게 경력 0년, 10년, 30년인 사람을 뜻하는지 불분명함. “가독성” 역시 누군가에겐 명확한 개념이지만, 실제론 0부터 무한대까지 다양한 스펙트럼임. Maxwell의 방정식은 누군가엔 너무 명확하지만 다른 누군가에겐 전혀 불투명함. 그래서 “코드는 읽기 쉬워야 한다”는 말은 과연 누구를 대상으로 한 것인지 늘 의문임
-
읽기 쉬운 코드는 독자를 배려해 인지적 부담을 최소화하는 코드를 의미함. 이게 레이어드 추상화, 디자인 패턴의 목표이기도 함. 물론 대상 독자의 전문성과 코드 기반 익숙함에 따라 달라지니까 주관적임. 하지만 주관적이란 이유로 가독성 자체를 부정한다는 건 좀 심함. Joyce의 '율리시스'와 Seuss의 'The Cat in the Hat' 둘 다 똑같이 읽기 쉽다고 할 수 없잖음
-
“가독성은 개념이 아니다”라는 주장에 동의하지 않음. 읽을 수 없는 코드는 저자 본인(혹은 AI)은 물론 누구도 못 읽는 코드임. 저자만 읽을 수 있는 코드도 역시 읽기 쉬운 게 아님
-
Maxwell 방정식 당시엔 진짜 어려웠지만, 지금 우리가 아는 식은 Heaviside 등이 더 다듬어 가독성이 좋아진 결과임
-
코드 일부의 “로컬 가독성”은 별 의미가 없다고 봄. 코드베이스 전반에 걸쳐 패턴이 일관되게 적용되면, 설령 그 패턴이 약간 복잡하더라도 전체적으로는 충분히 읽기 쉬운 코드가 될 수 있음. 일시적인 복잡성은 전체 코드 품질에 영향을 주지 않으면 괜찮음
-
가독성은 대개 ‘우연한 복잡성(accidental complexity)’을 줄이는 데 목적이 있음. 영화 시나리오 같은 수식도, 복잡한 알고리즘도, 표기가 나쁘면 이해 자체가 어려워짐. 결국 ‘코드는 누구에게 읽기 쉬워야 하는가’라는 질문엔, 해당 분야를 잘 아는 엔지니어가 문제는 익숙하지만 코드 자체는 못 본 상황에서도 읽을 수 있어야 함. 이는 논문과 비슷해서, 해당 연구자 그룹에는 읽기 쉬워야 한다고 생각함. No Silver Bullet 요약
-
-
“취향이 나쁜 엔지니어는 부서진 나침반처럼 결국엔 잘못된 방향을 제시한다”는 비유가 본질을 잘 설명한다고 생각함. 이런 ‘예측 가능하게 고장난’ 사람은 면담으로 걸러낼 수 있음. 오히려 더 위험한 건 ‘부분적으로 고장난 나침반’임. 겉보기엔 좀 돌아가다 싶다가 사실 언제나 딱 127도씩 틀려 있는 그런 유형임
- “부분적으로 고장난 나침반” 엔지니어의 구체적 예시를 들어줄 수 있는지 궁금함
-
이런 글들은 두 가지 이슈를 혼동하는 게 많음. 첫째, 취향이나 원칙과 상관없이 객관적으로 나쁜 결정(예: 리스트에서 O(n) 검색 vs 딕셔너리로 O(1) 검색)은 있음. 기술적이고 명확히 우열이 갈리는 게 존재함. 둘째, 나머지는 모두 트레이드오프임. map-reduce를 쓸지 일반 반복문 쓸지, 성능 상황, 가독성, 호환성 등만 따지면 됨. 여러 옵션 중 이유만 있다면 내 생각과 달라도 괜찮음. 문제는 오답이거나 트레이드오프 자체를 고려하지 않은 거임. 그땐 유지보수의 영역이고, 성능이나 빈도 등 상황에 따라 굳이 손대지 않을 수도 있음. 그 결정에 대한 “이유(why)”만 명확하면 다 인정함. 이런 게 진정으로 “취향”이라고 할 수 있는지는 잘 모르겠음
-
이 글의 문제는 “사람마다 중시하는 가치가 다르다”는 점을 너무 무맥락적으로 다룬다는 부분임. 실제론 엔지니어라면 대략 어느 가치가 문제에 가장 중요한지(=hard constraint)를 감지할 수 있어야 함. 이 hard constraint를 뺀 나머지 자유도를 “취향”이라고 보는 게 적절함. 아티스트로 치면 지정된 재료와 규격 이외에 자기만의 추가 제약이나 자유가 남아 있는 부분임. 소프트웨어 엔지니어의 좋은 취향은 ‘미학적으로는 미니멀하고, 자기 절제에는 최대치’를 추구하는 쪽과 유사함. 내가 생각하는 진짜 “취향이 나쁜” 경우는, 아무런 이유 없이 원칙을 깬 쪽임. 즉, 단순함을 ‘익숙함’으로 잘못 착각한 경우가 많았음
-
글 내 “가치”라는 항목은 Roy Fielding의 박사 논문의 소프트웨어 아키텍처의 속성과 연결됨. Fielding 논문은 REST로 주로 유명하지만, 실제로는 더 넓고 탄탄한 소프트웨어 아키텍처 논의임. 여러 “아키텍처 속성(확장성, 가독성, 유지보수성 등)”의 맥락에서 생각할 수 있게 해주며, 난 개인적으로 이런 속성 외에도 ‘아키텍처 제약’을 이해하는 것이 얼마나 중요한지 강조하고 싶음
-
제대로 된 엔지니어링(Principled engineering)은 당연해야 함. 그 위에 취향이 좋든 나쁘든 둘 다 가능함. 하지만 반대는 성립하지 않음. 엔지니어링 자체가 안 좋다면 취향은 의미 없음. 나쁜 취향은 엔지니어링의 효율을 저해할 순 있지만, 엔지니어링 그 자체를 불가능하게 만들진 않음. 엔지니어링은 기본적으로 취향을 뒷받침하는 역할임. 예를 들어 완벽하게 엔지니어링된 것일지라도 필요 없고 원하지 않는 것이라면 의미 없음
-
나쁜 취향은 결국 우리가 피하려는 불확실한 상황(X)으로 인도함. 내가 보기엔 좋은 취향이란 결국 앞으로 다가올 미래의 불확실성에 대비해, 코드베이스에 견고한 기반과 안전장치를 마련해놓는 것임. 이렇게 해야 위험에 빠지지 않음