/////
Search
Duplicate
🔊

일반

G1: 한 소스 파일에 여러 언어를 사용한다.

하나의 소스 파일에 3,4개의 언어가 있다면 정말 보기 좋을 것이다. 그렇지 않은가?
막 머릿속에서 컨텍스트 스위칭 돌아가면서 쟤 이해하고 얘 이해하고 혼란스러울 거다.
현실적으로 어려운 것 안다. 최대한 그 수를 줄이자.

G2: 당연한 동작을 구현하지 않는다.

함수를 구현할 것이라면 직관적으로 기대되는 바에 대한 요구를 충족시켜야 한다.
그렇지 않는다면 남들은 당신의 함수를 봤을 때, 구체적인 부분까지 확인할 것이다.

G3: 경계를 올바로 처리하지 않는다.

항상 끝을 조심해야 한다. 엣지 케이스는 언제나 우리를 불편하게 만드니까.

G4: 안전 절차 무시

안전 절차를 무시하면 끝이 좋지 못하다.
컴파일러 경고를 무시해버리면 당장은 편할지 몰라도 나중에 배로 돌려받을 걸?

G5: 중복

중복을 발견할 때마다 추상화할 기회로 간주하자.
추상화 수준을 높여 좋은 객체지향을 향한 발자국을 내딛을 기회다.
switch/caseif/else문의 조건을 거듭 확인하는 중복은 다형성으로 처리하는 것이 좋다.
알고리즘이 유사하나 약간의 코드가 다르다면 디자인 패턴을 떠올려서 해결해보자.
어디서든 중복을 발견하면 바퀴벌레를 본 것 마냥 없애버리자.

G6: 추상화 수준이 올바르지 못하다.

추상화는 저차원 상세 개념과 고차원 일반 개념을 분리한다.
그들이 같이 존재하는 것 자체만으로도 안티패턴이다. 유지보수를 해치고 문제가 생긴다.

G7: 기초 클래스가 파생 클래스에 의존한다.

효자도 아니고 부모가 어찌 자식에게 의존할 수 있는가.
예외는 있다. 파생 클래스가 수정될 일이 없다면 간혹 기초 클래스가 수정 클래스를 선택하는 코드가 존재한다.

G8: 과도한 정보

잘 정의된 모듈은 인터페이스가 아주 작다. 부실하게 정의된 모듈은 구질구질하다.
좋은 개발자는 클래스나 모듈 인터페이스가 노출할 함수를 제한, 제어할 줄 알아야 한다.
자료를 숨겨라, 인스턴스 변수를 숨겨라, 상수와 임시 변수를 숨겨라.
1만 하면 1만 알면 된다. 2만 하면 2만 하면 된다.
컴퓨터는 똑똑하지만 멍청해야 일을 잘한다는 것을 기억하자.

G9: 죽은 코드

절대 일어날 일이 없는 조건을 체크하는 if, case
throw 문이 없거나 발생할 일이 없는 try-catch
아무도 호출 않는 유틸리티 함수
죽은 코드는 적절한 장례식을 치루고 떠나보내자.

G10: 수직 분리

변수와 함수는 사용되는 위치에 가깝게 위치시킨다.
글 쓸 때, 비슷한 주제끼리 떨어뜨려 놓지 않지 않는가.
비공개 함수는 첫 호출이 일어난 메소드 블록 다음에 정의한다.

G11: 일관성 부족

일관적이지 않은 사람은 신뢰가 없다.
일관적인 코드는 빠른 이해를 가져다 준다.

G12: 잡동사니

필요 없는 건 지워라
방 정리는 잘 못해도 내가 이건 잘 할 수 있다.

G13: 인위적 결합

서로 무관한 개념을 인위적으로 결합하지 않는다.

G14: 기능 욕심

클래스 메서드는 자기 클래스의 인스턴스, 매개변수와 함수에만 관심을 가져야 한다.

G15: 선택자 인수

public int calculateWeeklyPay(boolean overtime)
플래그 인수 쓰지 말자.

G16: 모호한 인수

코드를 짤 때는 의도를 최대한 분명히 밝히자.

G17: 잘못 지운 책임

책임은 요구되어지는 바에 적절하게 배치되어야 한다.
Fruit 클래스가 PI를 가지고 있을 필요는 없다.

G18: 부적절한 static 함수

Math.max(double a, double b)는 좋은 정적 메서드다.
HourlyPayCalculator.calculatePay(employee, overtimeRate)는 좋지 않은 정적 메서드다.
불필요한 정적 메서드는 낭비다.
재정의할 가능성이 있다면 정적 메서드로 두지 말아라.

G19: 서술적 변수

프로그래밍은 논리적 글쓰기다.
가독성을 높이려면 처리 단계를 적절히 나누고 각 단계를 서술하듯 써야한다.

G20: 이름과 기능이 일치하는 함수

이름에서 기대되는 기능만 해야한다.
이름에서 기대되는 기능을 해야한다.

G21: 알고리즘을 이해하라.

구현이 끝났다고 하기 전에 본인이 구현한 함수의 알고리즘을 정확하게 이해해라.

G22: 논리적 의존성은 물리적으로 드러내라

의존하는 모듈이 상대 모듈에 대해 뭔가를 가정하면(즉, 논리적으로 의존하면) 안 된다.
의존하는 모든 정보를 명시적으로 요청하는 편이 좋다.

G23: if/else 혹은 switch/case 보다는 다형성을 사용하라

선택 유형 하나에는 switch 문을 한 번만 사용한다.
같은 선택을 수행하는 다른 코드에서는 다형성 객체를 생성해 switch 문을 대신한다.

G24: 표준 표기법을 따르라.

팀의 컨벤션은 업계 표준에 기반하여 작성하여야 한다.
팀의 컨벤션는 충분한 정보를 명시해야 한다.
인스턴스 변수 이름을 선언하는 위치
클래스/메서드/변수 이름을 정하는 방법
괄호를 넣는 위치 등
팀이 정한 표준은 팀원들 모두가 따라야 한다.

G25: 매직 숫자는 명명된 상수로 교체하라.

매직 숫자는 나만 알고 있는 암호와 같다.
상수명 등의 도움을 받아 처리하자.

G26: 정확하라

정확하게 처리하라.
코드에서의 모호성과 부정확을 제거하라.

G27: 관례보다 구조를 사용하라

설계가 결정 되었을 때, 이 결정을 강제하려면 규칙보다 관례를 사용하라.
구조 자체로 강제하는 것이 제일 좋다.
switch/case 문보다 추상 메서드가 있는 기초 클래스

G28: 조건을 캡슐화하라

부울 논리는 이해하기 어렵다.
age > constaraintAge보다 isOver(age)가 낫다.

G29: 부정 조건은 피하라

부정 조건은 긍정 조건보다 이해하기 어렵다.

G30: 함수는 한 가지만 해야 한다

함수는 한 가지만 수행하는 여럿 함수들로 나눠지고 이들 간의 상호작용으로 구성되어야 마땅하다.

G31: 숨겨진 시간적인 결합

어떠한 코드에 명백한 순서가 존재할 때, 이 순서를 명시하여아 한다.
이것이 명시되지 않아 순서대로 처리되지 않는다면 문제가 발생할 것이다.

G32: 일관성을 유지하라

일관성 있는 사람이 되어라

G33: 경계 조건을 캡슐화하라

+ 1과 같은 경계를 넘나드는 연산을 방지하자.
for i in range(5 + 1):

G34: 함수는 추상화 수준을 한 단계만 내려가야 한다

함수 내 모든 문장은 추상화 수준이 동일해야 한다.
그리고 그 추상화 수준은 현재 함수보다 한 단계 낮아야 한다.
추상화 수준은 너가 정하는 거다. 너가 설계한 계층대로 추상화 수준이 결정된다.

G35: 설정 정보는 최상위 단계에 둬라

추상화 최상위 단계에 둬야 할 상수들은 저차원 함수에 존재해서는 안 된다.
해당 추상화 단계에서 명시되어 있다면 해당 상수들은 그 메소드의 매개변수여야 한다.

G36: 추이적 탐색을 피하라

A 모듈이 B 모듈을 사용할 때, B 모듈이 C 모듈을 이용한다면
A 모듈은 C 모듈이 뭘 하는지 몰라야 한다.