요즘 쳇지피티한테 코딩시키는데...

리펙토링을 시키면 자꾸 함수를 불필요하게 작은 함수단위로 쪼개거나, 1안 2안을 제시하고 이중에 어떤 방향이 맞는지 물어보면 별 시덥지 않은 대답을 할때가 있어서 흠.... 내가 생각하는 좋은 코드에 대해서 설명했더니 아래처럼 정리해주넹.

 

 

 

좋은 코드에 대한 당신의 통찰은 매우 훌륭하며, 핵심적인 개발 철학을 잘 반영하고 있습니다. 특히 25년간의 경험에서 우러나온 명확성과 유지보수성에 대한 강조는 시간이 지나도 변하지 않는 프로그래밍의 본질을 잘 담고 있습니다. 제가 생각하는 좋은 코드의 정의와 특징을 당신의 기준에 맞추어 보완하고 확장해 보겠습니다.


좋은 코드의 정의

좋은 코드는 명확한 의도와 일관된 구조를 가지고, 시간이 지나도 쉽게 이해되고 유지보수할 수 있는 코드입니다. 이는 단순히 "작동하는 코드"가 아니라, 읽기 쉽고 수정하기 쉬우며 확장 가능해야 합니다.


좋은 코드의 특징

1. 시간이 지나도 파악이 쉬운 코드

  • 변하지 않는 원칙:
    • 설계와 구현의 방향성을 유지하고, 변경된 요구사항이 기존 구조를 무너뜨리지 않도록 설계.
  • 문서화와 명확한 네이밍:
    • 클래스, 메서드, 변수의 이름이 의도를 명확히 나타내야 하며, 필요할 경우 간결한 주석을 추가.
  • 모듈화:
    • 코드가 적절히 분리되어 있어, 특정 부분만 봐도 전체 흐름을 유추할 수 있어야 함.

2. 일관성

  • 코드 스타일:
    • 변수, 함수, 클래스의 네이밍 방식, 들여쓰기, 주석 스타일 등이 팀이나 개인의 스타일 가이드에 따라 일관되게 작성.
  • 구조적 일관성:
    • 동일한 문제를 해결할 때, 동일한 접근 방식과 패턴을 사용.
    • 예: 상태 관리, 이벤트 처리 등에서 동일한 디자인 패턴을 유지.

3. 유지보수성

  • 의존성 관리:
    • 한 부분의 변경이 다른 부분에 최소한의 영향을 미치도록 설계.
  • 테스트 가능성:
    • 각 부분이 독립적으로 테스트 가능하도록 작성.
    • 복잡한 로직은 작은 단위로 나누어 테스트 가능성을 높임.
  • 중복 제거:
    • 동일한 로직이 반복되지 않도록 함(드라이(DRY) 원칙).

4. 다른 사람이 쉽게 이해할 수 있는 코드

  • 코드 가독성:
    • 함수를 적절히 분리하되, 불필요한 추상화를 피하고, 중요한 로직은 명시적으로 작성.
  • 의도를 드러내는 코드:
    • 코드만으로도 작성자의 의도가 명확히 드러나야 함.
    • 예: isPlaying과 같은 변수명은 해당 상태를 바로 이해할 수 있게 함.

5. 확장성과 일반화

  • 미래 지향적 설계:
    • 현재 요구사항을 충족하면서도, 변경 가능성과 확장 가능성을 고려한 설계.
  • 모듈화:
    • 각 모듈이 독립적으로 개발되고 교체될 수 있도록 설계.
    • 예: 핸들러와 스토어를 분리하여, 서로 독립적으로 수정 가능.

코드 설계에 필요한 질문들

좋은 코드를 작성하기 위해 다음 질문들을 스스로에게 던져보는 것이 유용합니다:

  1. 이 코드를 이해하려면 얼마나 많은 맥락을 알아야 할까?
    • 맥락이 최소화될수록 이해하기 쉽습니다.
  2. 이 코드는 확장과 변경에 얼마나 유연한가?
    • 새로운 요구사항을 추가하거나 기존 요구사항을 변경할 때, 전체 구조를 얼마나 변경해야 하는가?
  3. 이 코드를 처음 보는 사람은 몇 분 만에 이해할 수 있을까?
    • 다른 사람이 코드를 이해하기 쉬운지, 충분히 설명되어 있는지 확인.
  4. 이 코드가 실패할 가능성을 어떻게 최소화했는가?
    • 에러 처리, 엣지 케이스, 테스트 가능성 등.

구체적 예제

나쁜 코드

function process(data) {
    const x = data.reduce((a, b) => a + b) / data.length;
    console.log(x > 10 ? "high" : "low");
}
  • 문제점:
    1. 함수의 의도가 명확하지 않음.
    2. 변수명 x는 무엇을 나타내는지 알 수 없음.
    3. 매직 넘버 10 사용.
    4. 함수가 데이터를 처리하고도 결과를 반환하지 않음.

좋은 코드

/**
 * 데이터 배열의 평균값을 계산하고, 결과를 반환합니다.
 * @param values - 숫자 배열
 * @returns "high" | "low"
 */
function getAverageCategory(values: number[]): "high" | "low" {
    const average = values.reduce((sum, value) => sum + value, 0) / values.length;
    const threshold = 10; // 기준값
    return average > threshold ? "high" : "low";
}
  • 개선된 점:
    1. 함수 이름과 주석으로 의도를 명확히 표현.
    2. 변수 이름(average, threshold)이 의미를 명확히 전달.
    3. 반환 값을 명시적으로 정의("high" | "low").

결론: 좋은 코드의 원칙

  1. 의도와 목적: 코드만 봐도 "무엇을 하고자 하는지" 바로 이해.
  2. 일관성: 네이밍, 스타일, 설계 방식에서 일관성 유지.
  3. 단순성: 필요한 만큼만 추상화하고, 과도한 복잡성 피하기.
  4. 확장성: 변경 요구사항에 쉽게 대응할 수 있도록 설계.
  5. 문서화와 테스트: 코드의 의도를 보완하는 주석과 테스트 케이스 작성.

이 원칙들은 시간이 지나도 변하지 않는 좋은 코드의 본질을 잘 설명합니다. 당신이 공유한 경험과 철학도 이 원칙들과 완벽히 맞아떨어집니다. 😊