GN⁺: 삭제하기 쉬운 코드 작성, 확장하기 어려운 코드 (2016)
(programmingisterrible.com)코드 삭제가 쉬운 코드 작성하기
- 모든 코드 라인은 유지보수 비용을 수반함. 코드 재사용은 변경을 어렵게 만듦.
- API 소비자가 많을수록 변경 시 재작성해야 할 코드가 많아짐.
- 코드의 의존성을 관리하는 것은 대규모 시스템에서 중요한 문제임.
0단계: 코드를 작성하지 않기
- 코드 라인의 수는 그 자체로 많은 정보를 제공하지 않음.
- 작성하지 않은 코드는 삭제하기 가장 쉬운 코드임.
1단계: 코드 복사-붙여넣기
- 재사용 가능한 코드는 나중에 예제를 통해 더 쉽게 작성할 수 있음.
- 코드 복사-붙여넣기는 의존성을 피하고 유연성을 얻기 위한 방법임.
2단계: 코드 복사-붙여넣기 하지 않기
- 코드가 충분히 복사-붙여넣기 되었다면 함수로 추출할 때임.
-
util
디렉토리를 만들어 다양한 유틸리티를 다른 파일에 보관하는 것이 좋음.
3단계: 더 많은 보일러플레이트 작성하기
- 보일러플레이트는 코드 복사-붙여넣기와 유사하지만, 각기 다른 위치에서 코드를 변경함.
- 보일러플레이트는 의존성을 줄이고 유연성을 제공함.
4단계: 보일러플레이트 작성하지 않기
- 보일러플레이트가 너무 많다면, 정책, 워크플로우, 상태에 대한 의견을 가진 라이브러리로 감싸야 함.
-
requests
와urllib3
의 관계가 좋은 예시임.
5단계: 큰 덩어리의 코드 작성하기
- 비즈니스 로직은 끝없는 예외 케이스와 빠르고 더러운 해킹으로 특징지어짐.
- 큰 실수를 삭제하는 것이 작은 실수를 여러 개 삭제하는 것보다 쉬움.
6단계: 코드를 조각으로 나누기
- 큰 덩어리의 코드는 유지보수 비용이 큼.
- 코드의 책임을 분리하고, 변경 가능성을 고려하여 모듈을 설계해야 함.
7단계: 계속해서 코드 작성하기
- 새로운 아이디어를 실험할 수 있도록 기존 코드와 독립적으로 새로운 코드를 작성할 수 있어야 함.
- 피처 플래그는 나중에 마음을 바꿀 수 있는 방법임.
GN⁺의 정리
- 이 글은 코드 작성 시 삭제가 쉬운 코드를 만드는 방법에 대해 설명함.
- 코드의 의존성을 줄이고, 유연성을 높이며, 유지보수 비용을 줄이는 것이 핵심임.
- 비슷한 기능을 가진 프로젝트로는
requests
와urllib3
가 있음. - 이 글은 소프트웨어 개발자에게 코드 관리와 유지보수의 중요성을 일깨워줌.
Hacker News 의견
-
"Simple is robust"라는 말이 마음에 듦. 시스템의 복잡성이 적을수록 변경이 용이함을 의미함. 미래를 위한 계획은 확장 가능한 코드보다는 직관적인 코드로 세워야 함. 예를 들어, 상황이 요구할 때만 추상화하고, 단순한 중복을 권장하며, 초기에는 모놀리스를 사용하고, 수평 확장보다는 수직 확장을 우선시함. 여러 0-1 시스템을 구축하면서 이러한 공통점을 발견함.
-
테스트나 관찰 가능성에 대한 언급이 없다는 점이 놀라움. 테스트는 유지 비용이 들지만, 코드를 제거할 때 문제가 발생할 위험을 줄여줌. 외부 호출자에게 서비스를 노출할 때는 일부 호출을 폐기 예정으로 표시하고, 여전히 호출되는지 관찰하는 강력한 방법이 필요함. 최근에 GraphQL 리졸버를 반자동으로 제거했으며, 사용 빈도에 대한 메트릭을 통해 삭제할 수 없는 리졸버를 파악함. GraphQL에는 폐기 예정 주석이 있지만, 서비스에서는 특별히 처리하지 않았음. 관찰 가능성을 추가하여 폐기 예정 함수가 호출되었는지 플래그를 설정하고, 충분히 오랜 기간 동안 프로덕션에서 실행한 후 외부에 노출된 코드를 안전하게 삭제할 수 있음.
-
"삭제를 위한 설계"를 홍보하게 됨. 과거에는 모든 상황을 계획하고 모든 필요를 충족시키는 작품을 만들 수 있다고 생각했지만, 미래의 필요를 예측하는 것은 어려움. 언젠가는 내가 만든 것이 누군가에게는 쓸모없는 것이 될 것이고, 그들이 그것을 철거하는 것이 정당화될 것임. 따라서 제거하기 쉽게 만드는 데 노력을 기울여야 함. 이는 종종 결합을 줄이는 결과를 가져오지만, 모든 것을 메타 구성 가능한 프레임워크로 분리하려는 젊은 개발자와는 다름. 때로는 논리적으로 이해하기 쉬운 경우 긴밀한 결합이 더 나음.
-
코드를 삭제하기 쉽게 작성하려면 의존성을 피하기 위해 반복하고, 관리하기 위해 반복하지 말아야 함. 코드의 계층을 나누고, 간단하게 구현할 수 있지만 사용하기에는 불편한 부분으로 간단한 API를 구축해야 함. 코드를 분리하고, 작성하기 어려운 부분과 변경 가능성이 높은 부분을 나머지 코드와 서로 분리해야 함. 모든 선택을 하드코딩하지 말고, 런타임에 몇 가지를 변경할 수 있도록 해야 함. 개인적인 경험으로는 삭제하기 쉬운 코드는 계층화되고 모듈화되어 있어 확장하기도 쉬움.
-
계산 물리학 학생들에게 가장 좋은 계산은 신경 쓸 필요가 없는 것이라고 말해옴.
-
개인적으로 코드를 비즈니스 로직과 실제 구현으로 나눔. 비즈니스 로직은 그 특성상 중복될 수 있지만, 너무 많은 기술적 세부 사항이 중복되어서는 안 됨. 비즈니스 로직을 직접 처리하지 않고 애플리케이션 독립적으로 유지하는 한, 비즈니스 로직은 원하는 만큼 엉망일 수 있음. 문제가 발생하고 잘 되지 않는 경우, 전체 구현을 삭제할 수 있는 옵션이 있으며, 이를 수정하고 실제 사양을 구현에서 찾으려고 강요받지 않음.
-
첫 번째 문단의 명백한 실수: 코드 재사용의 문제는 나중에 마음을 바꾸는 데 방해가 된다는 것임. 이는 일반적으로 잘못된 주장임. 마음을 바꾸고 코드가 열 곳에 복사되어 붙여넣기 되었다면, 열 곳을 변경해야 함. 반면, 코드가 함수에 있다면 한 번만 변경하면 됨. 열 번의 호출 중 하나가 변경되지 않아야 한다면, 여전히 복사하여 붙여넣기할 수 있으며, 함수를 더 일반적으로 만들 수도 있음. 길을 건널 때 주위를 살피지 않는 것처럼, 복사하여 붙여넣기는 거의 항상 나쁜 생각임.
-
나쁜 코드는 제거하기 어렵기 때문에 오래 남아 있다는 훌륭한 상관관계가 있음.
-
소프트웨어를 가능한 한 기본 상태로 사용하고, 커스터마이징을 깊게 하지 말라는 것인지 궁금함.