‘적용 방법’을 아는 것과 ‘제때 적용’할 줄 아는 것은 다르다. 리팩터링이 필요한, 때로는 아주 절실한 코드들에 일정한 패턴이 있다. 따라서 먼저 이 장을 읽고 코드가 풍기는 냄새(악취)가 무엇인지 찾자. 그런 다음 여러가지 리팩터링 기법을 찾아 읽고 그 냄새를 없애는 데 도움이 될지 생각해보도록 하자.
코드 이해력, 가독성 X
코드는 단순하고 명료하게 작성해야 한다. 코드를 명료하게 표현한느 데 가장 중요한 요소 하나는 바로 ‘이름’이다. 그래서 함수, 모듈, 변수, 클래스 등은 그 이름만 보고도 각각이 무슨 일을 하고 어떻게 사용해야 하는지 명확히 알 수 있도록 엄청나게 신경 써서 이름을 지어야 한다.
실수와 에러 발생할 확률이 높아진다.
똑같은 코드 구조가 여러 곳에서 반복된다면 하나로 통합하여 더 나은 프로그램을 만들 수 있다. 코드가 중복되면 각각을 볼 때마다 서로 차이점은 없는지 주의 깊게 살펴봐야 하는 부담이 생긴다.
이해하기 어려움, 재사용성 떨어짐
오랜 기간 잘 활용되는 프로그램들은 하나같이 짧ㅇ은 함수로 구성했다. 간접 호출의 효과, 즉 코드를 이해하고, 공유하고, 선택하기 쉬워진다는 장점은 함수를 짧게 구성할 때 나오느 것이다.
짧은 함수로 구성된 코드를 이해하기 쉽게 만드는 가장 확실한 방법은 좋은 이름이다. 함수 이름을 잘 지어두면 본문 코드를 볼 이유가 사라진다. 그러기 위해서는 훨씬 적극적으로 함수를 쪼개야 한다.
함수로 묶는 코드는 여러 줄일 수도 있고 단 한 줄일 수도 있다. 심지어 원래 코드보다 길어지더라도 함수로 뽑는다. 단, 함수 이름에 코드의 목적을 드러내야 한다.
사용하기 어려움, 잦은 실수
매개변수 목록이 길어지면 그 자체로 이해하기 어려울 때가 많다.
최악, 유령같은 버그 출몰
전역데이터는 악취 중 가장 지독한 축에 속한다. 유령같은 원격작용처럼, 버그는 끊임없이 발생하는데 그 원인이 되는 코드를 찾아내기가 굉장히 어렵다. 접근자 함수들을 클래스나 모듈에 집어넣고 그 안에서만 사용할 수 있도록 접근 범위를 최소로 줄이는 것도 좋다.
예상하지 못한 곳에서 데이터를 변경
데이터를 변경했더니 예상치 못한 결과나 골치 아픈 버그로 이어지는 경우가 종종 있다. 따라서 함수형 프로그래밍
에서는 데이터는 절대 변하지 않고, 데이터를 변경하려면 반드시 변경하려는 값에 해당하는 복사본을 만들어서 반환한다는 개념을 기본으로 삼고 있다.
한 곳에서 너무 많은 일을 하거나, 여러 모듈이 다 엮여있는 경우
다양한 이유로 수정을 해야함
소프트웨어의 구조를 변경하기 쉬운 형태로 조직해야 한다. 코드를 수정할 때는 시스템에서 고쳐야 할 딱 한 군데를 찾아서 그 부분만 수정할 수 있기를 바란다. 다시 말해, 한 책임만 가지고 있는 모듈로 만들어야 한다. 뒤엉킨 변경은 단일 책임 원칙(Single Responsibility Principle)SRP가 제대로 지켜지지 않을 때 나타난다.
한 모듈/클래스/함수를 수정하면 다른 곳에서도 수정해야 한느 경우
코드를 변경할 때마다 자잘하게 수정해야 하는 클래스가 많을 때 나는 냄새이다.
다른 모듈과 더 밀접하게 상호작용
프로그램을 모듈화 할 때는 코드를 여러 영역으로 나눈 뒤 영역 안에서 이뤄지는 상호작용은 최대한 늘리고, 영역 사이에서 이뤄지는 상호작용은 최소로 줄이는 데 주력한다. 디자인 패턴 중 전략 패턴, 방문자 패턴, 자기위임을 사용하면 뒤엉킨 변경 냄새를 없앨 수 있다. 가장 기본이 되는 원칙은 함께 변경할 대상을 한데 모으는 것이다.
여러곳에서 항상 함께 쓰임
데이터 항목은 서로 어울려 노는 것을 좋아한다. 몰려다니는 데이터 뭉치는 보금자리를 따로 마련해줘야 마땅하다.
관련된 코드가 여기저기
자신에게 주어진 문제에 딱 맞는 기초 타입(화폐, 좌표, 구간 등)을 직접 정의하기를 몹시 꺼리는 사람이 많다.
새로운 타입이 추가되면 여기저기 업데이트
switch문은 모조리 조건부 로직을 다형성으로 바꾸기로 없애야 할 대상이라고 주장한다. 중복된 switch문이 문제가 되는 이유는 조건절을 하나 추가할 때마다 다른 switch문들도 모두 찾아서 함께 수정해야 하기 때문이다. 이럴 때 다형성은 반복된 switch문이 내뿜는 사악한 기운을 제압하여 코드베이스를 최신 스타일로 바꿔주는 세련된 무기인 셈이다.
절차형의 코드 → 사이드 이펙
불필요한 함수, 클래스, 인터페이스
혹시 모르니, 미래를 위해서 써 놓은 코드
특정한 상황에서만 사용됨, 이해도 낮음
내부 로직이 노출됨
단순 전달만 하는 불필요한 코드
모듈 사이 데이터 거래 → 결합도 높아져 복잡해짐
중복 코드 많아질 수 있으며, 뒤엉킨 변경이 일어날 수 있다.
비슷한 역할인데 인터페이스가 다른경우 → 서로 대체성이 낮아짐, 재사용성이 낮아짐.
필요한 로직이 여기저기
상속의 오용, 남용은 위험함
필요 없는 주석은 악!
좋은글 같아서 들어왔는데... 역시 '주'님...👍👍👍