기이한 이름
- 마땅한 변수명이 떠오르지 않는다면 코드에 여러 기능이 있기 때문은 아닌지 의심하기.
- 동의어 (display, show / render, paint, print)를 통일하고 풍부한 어휘력은 숨기기..
함수 선언 바꾸기
,변수 이름 바꾸기
,필드 이름 바꾸기
중복 코드
- 똑같은 코드 구조가 여러 곳에서 반복된다면 하나로 통합하자.
함수 추출하기
,문장 슬라이드하기
,메서드 올리기
긴 함수
- 주석을 달아야 할 만한 부분은 무조건 함수로 만든다.
- 무엇을 하는지 코드가 설명해주지 못한다면 함수로 만들자.
함수 추출하기
,임시 변수를 질의 함수로 바꾸기
,매개변수 객체 만들기
,객체 통째로 넘기기
긴 매개변수 목록
- 매개변수 목록이 길어지면 그 자체로 이해하기 어렵다.
매개변수를 질의 함수로 바꾸기
,객체 통째로 넘기기
,매개변수 객체 만들기
,플래그 인수 제거하기
,여러 함수를 클래스로 묶기
전역 데이터
- 전역 데이터는 코드베이스 어디에서든 건드릴 수 있고 값을 누가 바꿨는지 찾아낼 메커니즘이 없다.
변수 캡슐화하기
가변 데이터
- 데이터 변경으로 인한 버그때문에 함수형 프로그래밍에서는 데이터는 절대 변하지 않고, 데이터를 변경하려면 반드시 변경하려는 값에 해당하는 복사본을 만들어서 반환하고 있다.
- 하지만 함수형 언어가 프로그래밍에서 차지하는 비중은 적고 변수 값을 바꿀 수 있는 언어를 사용하는 프로그래머가 더 많다.
변수 캡슐화하기
,변수 쪼개기
,문장 슬라이드하기
,함수 추출하기
,질의 함수와 변경 함수 분리하기
,세터 제거하기
,파생 변수를 질의 함수로 바꾸기
,여러 함수를 클래스로 묶기
,여러 함수를 변환 함수로 묶기
,참조를 값으로 바꾸기
뒤엉킨 변경
- 단일 책임 원칙(SRP)이 제대로 지켜지지 않을 때 나타난다.
- 하나의 모듈이 서로 다른 이유들로 인해 여러 가지 방식으로 변경되는 일이 많을 때 발생한다.
단계 쪼개기
,함수 옮기기
,함수 추출하기
,클래스 추출하기
산탄총 수술
- 코드를 변경할 때마다 변경할 부분이 코드 전반에 퍼져 있어 찾기 어렵고 수정할 곳을 놓치지 쉬운 경우다.
- 작은 함수와 클래스를 권장하지만, 코드를 재구성하는 중간 과정에서는 큰 덩어리로 뭉쳐져도 된다.
함수 옮기기
,필드 옮기기
,여러 함수를 클래스로 묶기
,여러 함수를 변환 함수로 묶기
,단계 쪼개기
,함수 인라인하기
,클래스 인라인하기
기능 편애
- 프로그램을 모듈화할 때는 코드를 여러 영역으로 나눈 뒤 영역 안에서 이뤄지는 상호작용은 최대한 늘리고 영역 사이에서 이뤄지는 상호작용은 최소로 줄이는 데 주력한다.
- 기능 편애는 자기가 속한 모듈 함수, 데이터보다 다른 모듈의 함수, 데이터와 상호작용 할 일이 더 많을 때 풍기는 냄새다.
함수 옮기기
,함수 추출하기
,전략 패턴
,방문자 패턴
데이터 뭉치
- 몰려다니는 데이터 뭉치는 보금자리를 따로 마련해줘야 한다.
클래스 추출하기
,매개변수 객체 만들기
,객체 통째로 넘기기
기본형 집착
- 금액을 숫자형으로 계산하거나, 물리량을 계산할 때 단위를 무시하고, 범위도 if(a < upper && a> lower)처럼 처리하는 코드가 많다.
- 전화번호를 단순히 문자 집합으로만 표현하기엔 아쉬움이 많다.
- ex) 인치를 숫자로 쓰지말고 인치 객체를 만들자.
inch.value
를 비교하란 뜻인듯.
기본형을 객체로 바꾸기
,타입 코드를 서브클래스로 바꾸기
,조건부 로직을 다형성으로 바꾸기
,클래스 추출하기
,매개변수 객체 만들기
반복되는 switch문 📕
- 조건절을 하나 추가할 때마다 다른 switch문들도 모두 찾아서 함께 수정해야 하는 문제가 있다.
조건부 로직을 다형성으로 바꾸기
반복문
- filter, map 같은 파이프라인 연산을 사용하면 코드에서 각 원소들이 어떻게 처리되는지 쉽게 파악할 수 있다.
반복문을 파이프라인으로 바꾸기
성의 없는 요소
- 만든 구조가 필요없어진다면 없애자.
함수 인라인하기
,클래스 인라인하기
,계층 합치기
추측성 일반화
- 미래를 대비해 당장은 필요 없는 모든 종류의 hooking 포인트와 특이 케이스 처리 로직을 작성해둔 코드는 좋지 않다.
- 실제 사용하면 다행이지만, 그렇지 않는다면 시간 낭비일 뿐이다.
계층 합치기
,함수 인라인하기
,클래스 인라인하기
,함수 선언 바꾸기
,죽은 코드 제거하기
임시 필드
- 특정 상황에서만 값이 설정되는 필드를 가진 클래스의 경우 사용자에게 쓰이지 않는 것처럼 보이는 필드가 존재하는 이유를 파악하느라 시간을 써야하는 문제가 있다.
클래스 추출하기
,함수 옮기기
,특이 케이스 추가하기
메시지 체인
- 메시지 체인은 클라이언트가 한 객체를 통해 다른 객체를 얻은 뒤 방금 얻은 객체에서 또 다른 객체를 요청하는 식으로, 다른 객체를 요청하는 작업이 연쇄적으로 이어지는 코드를 말한다.
- 내비게이션 중간 단계를 수정하면 클라이언트 코드도 수정해야 한다.
위임 숨기기
,함수 추출하기
,함수 옮기기
중개자
- 중개자가 지나치게 많을 경우(과반수) 중개자를 제거하여 실제로 일을 하는 객체와 직접 소통하자.
중개자 제거하기
,함수 인라인하기
내부자 거래
- 모듈 사이의 데이터 거래가 많으면 결합도가 높아진다. 그 양을 최소로 줄이자.
함수 옮기기
,필드 옮기기
,위임 숨기기
,서브클래스를 위임으로 바꾸기
,슈퍼클래스를 위임으로 바꾸기
거대한 클래스
- 한 클래스가 너무 많은 일을 하려다보면 필드 수가 늘어나고 중복 코드가 생기기 쉽다.
클래스 추출하기
,슈퍼클래스 추출하기
,타입 코드를 서브클래스로 바꾸기
서로 다른 인터페이스의 대안 클래스들
- 클래스는 필요에 따라 언제든 다른 클래스로 교체할 수 있다는 장점이 있다. 이를 활용하려면 교체하려는 인터페이스가 같아야 한다.
함수 선언 바꾸기
,함수 옮기기
,슈퍼클래스 추출하기
데이터 클래스
- 데이터 클래스란 데이터 필드와 게터/세터 메서드로만 구성된 클래스를 말한다.
- 데이터 저장 용도로만 쓰이다 보니 다른 클래스가 너무 깊이까지 다룰 때가 많다.
레코드 캡슐화하기
,세터 제거하기
,함수 옮기기
,함수 추출하기
,단계 쪼개기
상속 포기
- 상속을 포기했을 때 문제가 생긴다면
- 같은 계층에 서브클래스를 하나 만들고
메서드 내리기
,필드 내리기
를 활용해서 물려받지 않을 부모 코드를 모조리 새로 만든 서브클래스로 넘긴다. 📕
- 인터페이스를 따르지 않는다면
서브클래스를 위임으로 바꾸기
,슈퍼클래스를 위임으로 바꾸기
를 활용해 상속 매커니즘에서 벗어나보자.- 상속은 단일 책임 원칙에 위배된다. 부모에 대한 의존도가 높아진다.
주석
- 주석이 장황하면 코드를 잘못 작성했기 때문인 경우가 많다.
함수 추출하기
,함수 선언 바꾸기
,어서션 추가하기
얘기해보고 싶은 것
- 클래스 형태의 코드를 짜려고 해야 할까?