65535.log
로그인
65535.log
로그인
[클린코드] 17장 냄새와 휴리스틱
JUN
·
2024년 8월 19일
팔로우
0
법칙
클린코드
클린코드 정수
0
클린코드
목록 보기
14/14
17장 냄새와 휴리스틱
주석.
C1: 부적절한 정보
다른 시스템에 저장할 정보는 주석으로 적절하지 않음.
변경 이력 등 메타 정보는 소스 코드를 번잡하게 만듦.
주석은 코드와 설계에 기술적인 설명을 부연하는 수단.
C2: 쓸모없는 주석
오래된, 엉뚱한, 잘못된 주석은 쓸모없음.
쓸모없어진 주석은 빨리 삭제하는 것이 좋음.
쓸모없는 주석은 코드와 무관하게 따로 놀며 코드를 그릇된 방향으로 이끔.
C3: 중복된 주석
코드만으로 충분한 내용을 설명하는 주석은 중복된 주석임.
주석은 코드만으로 다하지 못하는 설명을 부연하는 역할을 해야 함.
C4: 성의 없는 주석
작성할 가치가 있는 주석은 잘 작성할 가치도 있음.
시간을 들여 간결하고 명료하게 작성해야 함.
C5: 주석 처리된 코드
주석 처리된 코드는 오래되거나 불필요한 코드일 가능성이 큼.
소스 코드 관리 시스템이 이전 버전을 기억하므로 주석 처리된 코드는 즉각 삭제하는 것이 좋음.
환경.
E1: 빌드 과정의 단순화
빌드 과정은 단일 명령어로 완료되어야 하며, 소스 코드 관리 시스템에서 개별적으로 체크아웃할 필요 없이 전체를 한 번에 체크아웃하고 빌드할 수 있어야 함.
SVN을 통해 프로젝트를 체크아웃한 후, 한 명령어로 모든 것을 빌드할 수 있어야 함.
E2: 테스트 프로세스의 단순화
모든 단위 테스트는 한 번에 실행할 수 있어야 하며, IDE에서도 버튼 하나로 전체 테스트를 실행할 수 있어야 함.
셸에서도 단일 명령어로 모든 테스트를 실행할 수 있어야 하며, 이는 개발자에게 중요한 기능임.
함수.
F1: 함수의 인수 개수 최소화
함수의 인수 개수는 작을수록 좋으며, 가능하면 인수 없이 함수를 구현하는 것이 이상적임.
최대한 한 개 이내의 인수를 가진 함수를 설계하고, 네 개 이상의 인수는 사용을 피해야 함.
F2: 출력 인수의 사용 제한
함수에서는 출력 인수를 사용하지 말고, 대신 함수가 속한 객체의 상태를 변경하는 방식을 사용해야 함.
함수는 입력을 받아 처리한 후에 객체의 상태를 변화시키는 방식으로 설계되어야 함.
F3: 플래그 인수의 사용 제한
boolean 타입의 플래그 인수는 함수의 여러 기능을 명시적으로 나타내는 것이므로 혼란을 초래할 수 있으며, 가능하면 피해야 함.
함수 호출 시 다양한 옵션을 플래그로 전달받는 방식은 코드의 가독성과 유지보수성을 저해할 수 있음.
F4: 죽은 함수 제거
실행되지 않는 함수는 시스템에서 삭제해야 하며, 이는 코드의 불필요한 복잡성을 줄이는 데 중요함.
사용되지 않는 함수는 삭제하고, 시스템에서 죽은 코드를 제거함으로써 코드 베이스를 깔끔하게 유지해야 함.
일반
G1: 소스 파일에서의 다중 언어 사용 최소화
소스 파일은 하나의 언어로 작성하는 것이 이상적이지만 현실적으로 여러 언어를 사용해야 할 경우, 최대한 언어의 수와 범위를 줄이는 것이 중요함.
Java 파일 내에 XML, HTML, JavaScript 등의 다양한 언어를 포함하지 않도록 노력해야 함.
G2: 기대하는 동작의 구현
함수나 클래스는 다른 프로그래머가 기대할 수 있는 동작을 제공해야 하며, "최소 놀람의 원칙"에 따라 일관된 동작을 구현해야 함.
함수가 입력받은 문자열을 정확히 enum 값으로 변환하거나, 대소문자를 구분하지 않고 처리하는 등의 구현이 필요함.
G3: 경계 조건의 올바른 처리
코드는 모든 경계 조건에서 올바로 동작해야 하며, 모든 예외 상황을 고려하여 테스트 케이스를 작성하는 것이 중요함.
코드에서 예외 상황을 처리하지 않고 흘려보내지 않고, 모든 경계 조건을 명확히 처리해야 함.
G4: 안전 절차의 중요성
안전 절차를 무시하면 시스템에 심각한 위험이 발생할 수 있으며, 컴파일 경고를 무시하거나 실패하는 테스트 케이스를 미루는 태도 역시 위험할 수 있음.
serialVersionUID의 직접 제어와 같은 절차적 결정은 신중하게 이루어져야 하며, 시스템의 안정성을 위해 필수적인 절차를 준수해야 함.
G5: 코드의 중복 최소화
중복된 코드는 추상화를 통해 제거되어야 하며, 함수 내에서 반복되는 코드는 하위 루틴으로 분리하거나 다형성을 이용해 해결해야 함.
코드를 추상화하여 중복을 제거하면 유지보수성과 코드의 응집력이 향상되며, 디자인 패턴을 활용해 중복을 최소화해야 함.
G6: 올바른 추상화 수준 유지
추상화는 저차원 세부 사항을 고차원 개념과 분리해야 하며, 상수나 변수와 같은 세부 사항은 기초 클래스에 포함하고, 고차원 개념은 파생 클래스에 포함해야 함.
추상 클래스와 인터페이스를 통해 코드를 추상화하고, 모듈이나 컴포넌트도 분리하여 정리해야 코드의 응집성을 높일 수 있음.
G7: 의존성 관리
기초 클래스는 파생 클래스에 의존해서는 안 되며, 독립적인 구성 요소로 분리해야 시스템의 유연성을 유지할 수 있음.
기초 클래스가 파생 클래스의 구현에 대해 직접적인 의존성을 가지면 시스템의 확장성이 제한될 수 있으므로, 이를 피해야 함.
G8: 인터페이스의 간결성 유지
잘 정의된 인터페이스는 많은 함수를 제공하지 않고도 충분히 동작할 수 있어야 하며, 결합도를 낮추는 것이 중요함.
인터페이스는 필요한 기능만을 제공하고, 불필요한 함수나 변수는 숨겨야 함.
G9: 죽은 코드 제거
실행되지 않는 코드는 시스템에서 제거해야 하며, 이는 코드의 복잡성을 줄이고 시스템의 유지보수성을 높이는 데 도움이 됨.
사용되지 않는 변수나 함수, 불가능한 조건을 확인하는 코드 등은 제거되어야 하며, 이는 시스템의 안정성과 가독성에 긍정적인 영향을 미침.
G10: 과도한 최적화 피하기
최적화는 시스템이 충분히 실행되지 않을 때에만 신경쓰도록 하고, 미리 최적화하는 것은 시간 낭비일 수 있음.
시스템에서 실질적으로 문제가 되는 부분만을 최적화하고, 일반적인 성능 향상을 위해 지나치게 시간을 낭비하지 않도록 주의해야 함.
G11: 코드의 단순성 강조
코드는 가능한 한 단순하게 유지해야 하며, 직관적이고 명확한 구현이 필요함.
코드를 간결하게 유지하면 읽기 쉽고 이해하기 쉬워지며, 디버깅이나 유지보수 과정에서의 실수를 줄일 수 있음.
G12: 프로그래머의 편리함 고려
코드는 다른 개발자들도 쉽게 이해하고 수정할 수 있도록 작성해야 하며, 효율적인 작업을 가능하게 하는 도구나 기법을 적극적으로 활용해야 함.
적절한 주석과 문서화, 일관된 코드 스타일 등은 코드의 가독성을 높이고, 개발자들이 협업할 때 편리함을 제공함.
G13: 인위적 결합
인위적 결합은 서로 무관한 개념을 강제로 결합하는 것을 말함. 예를 들어, enum이나 범용 static 함수를 특정 클래스에 속하게 만드는 것은 이 개념에 해당함. 이는 코드를 의도치 않게 복잡하게 만들 수 있음.
G14: 기능 욕심
기능 욕심은 클래스 메서드가 다른 클래스의 변수와 함수에 너무 많이 의존하는 것을 의미함. 이는 객체 지향 설계 원칙을 위배할 수 있으며, 필요 이상으로 클래스 간 결합을 높이는 결과를 초래할 수 있음.
G15: 선택자 인수
선택자 인수는 함수의 동작을 선택하기 위해 넘겨주는 인수를 말함. 이는 여러 함수를 하나로 합치는 결과를 초래할 수 있으며, 코드의 가독성을 떨어뜨릴 수 있음. 함수 호출 시 목적을 명확히 드러내는 것이 중요함.
G16: 모호한 의도
모호한 의도는 코드에서 의도를 명확하게 드러내지 않는 것을 말함. 이는 코드를 이해하고 유지보수하기 어렵게 만들 수 있으며, 코드 가독성을 저하시킬 수 있음. 명확하고 직관적인 변수명과 함수명을 사용하는 것이 중요함.
G17: 잘못 지운 책임
잘못 지운 책임은 한 모듈이 다른 모듈에 대해 논리적인 의존성을 가지고 있지만 이를 물리적으로 드러내지 않는 경우를 의미함. 이는 코드를 예상치 못한 방향으로 복잡하게 만들 수 있음.
G18: 부적절한 static 함수
부적절한 static 함수는 특정 인스턴스와 관련이 있는 기능을 static으로 정의하는 것을 말함. 이는 객체 지향 설계 원칙을 위배할 수 있으며, 코드의 유연성을 저하시킬 수 있음. 인스턴스 함수로 정의할 수 있는지 고민해야 함.
G19: 서술적 변수
서술적 변수는 계산의 여러 단계에서 중간값으로 사용되는 변수명을 명확하고 서술적으로 지으면 코드의 가독성을 높일 수 있음. 코드를 이해하고 유지보수하기 쉽게 만드는 데 중요한 역할을 함.
G20: 이름과 기능이 일치하는 함수
이름과 기능이 일치하지 않는 함수는 코드의 이해를 어렵게 만들 수 있음. 함수의 이름을 통해 함수가 어떤 기능을 수행하는지 명확하게 드러나야 함.
G21: 알고리즘을 이해하라
코드를 작성할 때는 구현한 알고리즘을 완전히 이해하고 작성해야 함. 단순히 테스트 케이스만 통과한다고 해서 충분하지 않으며, 알고리즘이 코드의 의도를 정확하게 반영해야 함.
G22: 논리적 의존성은 물리적으로 드러내라
한 모듈이 다른 모듈에 논리적으로 의존한다면 이를 코드에서 명시적으로 드러내야 함. 논리적 의존성만으로는 부족하며, 코드의 예상치 못한 동작을 방지할 수 있음.
G23: If/Else 혹은 Switch/Case 문보다 다형성을 사용하라
If/Else 혹은 Switch/Case 문보다 다형성을 사용하는 것이 바람직함. 이는 객체 지향 설계의 원칙을 따르며, 코드의 유연성과 확장성을 높이는 데 도움이 됨.
G24: 표준 표기법을 따르라
팀 내에서 사용하는 표준 표기법을 따르는 것이 중요함. 이는 코드의 일관성을 유지하고 팀원들 간 협업을 원할하게 만드는 데 기여함.
자바.
J1: 긴 import 목록을 피하고 와일드카드를 사용하라.
패키지에서 둘 이상의 클래스를 사용하면
“*”
를 사용할 것.
J2: 상수는 상속하지 않는다.
상수를 사용할 때는
private static final
int
TENTHS_PER_WEEK
=
400
;
과 같이 private로 사용할 것.
상수를 상속받고 싶을때는 static import 를 사용할 것
import
static Constants
.
*
;
J3: 상수 vs Enum
상수 상속보다는 Enum을 사용하는게 좋음
메서드, 필드도 사용가능하니 참고할 것.
이름
N1: 서술적인 이름을 사용하라
소프트웨어의 진화와 함께 의미가 변하는 이름을 신중하게 선택함. 이름은 코드의 가독성에 중대한 영향을 미침. 코드를 이해하는 데 있어 신중하게 선택된 서술적인 이름은 필수적임.
N2: 적절한 추상화 수준에서 이름을 선택하라
구현을 드러내는 이름보다는 클래스나 함수가 위치한 추상화 수준을 반영하는 이름을 선택함. 추상화 수준을 고려하여 이름을 지으면 코드 이해가 더 쉬워짐.
N3: 가능하면 표준 명명법을 사용하라
표준 명명법을 사용하면 코드를 읽고 이해하기 쉬워짐. 프로젝트에 맞는 명명 규칙을 정하고 일관성 있게 사용함.
N4: 명확한 이름을 선택하라
함수나 변수의 목적이 명확히 드러나도록 이름을 선택함. 이름만으로 함수가 수행하는 작업을 명확히 이해할 수 있어야 함.
N5: 긴 범위는 긴 이름을 사용하라
변수나 함수의 범위가 커질수록 이름을 길고 정확하게 짓음. 범위가 작을 때는 간결한 이름을 사용해도 되지만, 범위가 커질수록 이름을 확실하게 지어야 함.
N6: 인코딩을 피하라
유형이나 범위 정보를 이름에 인코딩하지 않음. 명확하고 중복되지 않는 이름을 선택하여 코드의 가독성을 높임.
N7: 이름으로 부수 효과를 설명하라
함수나 변수의 이름을 통해 부수적인 효과를 알 수 있도록 함. 이름만으로도 함수나 변수가 수행하는 작업을 이해할 수 있어야 함.
테스트
T1: 불충분한 테스트
충분한 테스트 케이스 필요
테스트되지 않는 조건이나 계산이 있으면 불완전
T2: 커버리지 도구를 사용하라!
테스트 커버리지 도구 사용
테스트가 빠진 부분을 시각적으로 확인
T3: 사소한 테스트를 건너뛰지 마라
사소한 테스트도 중요
문서적 가치 제공
T4: 무시한 테스트는 모호함을 뜻한다
불분명한 요구사항은 주석 또는 @Ignore로 표시
모호한 테스트 케이스는 컴파일 가능한지 확인
T5: 경계 조건을 테스트하라
경계 조건 테스트 중요
중앙 조건보다 경계 조건에서 실수 빈번
T6: 버그 주변은 철저히 테스트하라
버그 주변 함수 철저히 테스트
다른 버그 발견 가능성 높음
T7: 실패 패턴을 살펴라
테스트 케이스 실패 패턴 분석
실패 패턴으로 문제 진단
합리적인 순서로 정렬된 테스트 케이스 중요
JUN
순간은 기록하고 반복은 단순화하자 🚀
팔로우
이전 포스트
[클린코드] 14장 점진적인 개선
0개의 댓글
댓글 작성