책 소개
요약
시스템 내에 오래된 코드를 다루는 방법을 배울 수 있다. 오래된 코드, 즉 레거시 코드는 그 코드에 익숙한 사람도 없고, 테스트 루틴도 없어 관리하기 어렵다. 저자는 다년간의 현장 경험과 실제 코드를 바탕으로 다양한 기법을 소개한다. 여러 언어뿐만 아니라, 현업에서 사용되는 도구에 대해 현실적인 조언을 해준다. 코드 내 의존 관계 해결, 효과적 테스팅 방법 등 24가지 기법을 통해 시스템의 낡은 코드를 변경, 관리하는 데 있어 많은 통찰력을 줄 것이다.
추천의 글
유능한 소프트웨어 개발자라면 누구나 요구 사항이 변경될 것을 감안해 설계하고자 한다.
이것은 해결하기 매우 어려운 문제처럼 보인다. 실제로 너무 어렵기 때문에 거의 모든 시스템은 서서히 부패해 결국 망가져버린다. 이 부패는 침투력이 매우 강하며, 이처럼 부패한 프로그램을 가리키는 특별한 이름이 존재한다. 바로 ‘레거시 코드(legacy code)’다.
레거시 코드, 이 단어는 프로그래머의 마음속에 구토를 일으키는 단어다. 마치 끈적이는 거머리와 날카로운 침을 가진 날벌레들로 뒤덮인 덤불 천지의 음산한 늪지대를 걸어가는 것과 같은 이미지를 연상시킨다. 암흑, 점액, 고인 물, 악취라고 불러도 좋다. 우리가 처음 느꼈던 프로그래밍의 강렬한 기쁨도 레거시 코드를 다뤄야 하는 고통에 희석되기 십상이다.
최초에 작성했던 코드가 레거시 코드로 전락하지 않도록 막는 방법을 찾기 위해 수많은 사람들이 노력해왔다. 프로그래머가 시스템의 간결함을 유지하는 데 도움을 줄 수 있는 원칙이나 패턴, 실행 방법 등을 설명하는 책은 이미 많다. 하지만 이 책의 저자 페더스는 지금까지 간과됐던 것에 대한 통찰력을 제시하고 있다. 예방만으로는 충분하지 않다. 최선의 원칙을 숙지하고 최선의 패턴을 사용하며 최선의 실행 방법을 따르는 가장 잘 훈련된 개발 팀조차 때때로 일을 망칠 수 있다. 부패는 계속 쌓여가므로 부패를 방지하는 것만으로는 충분하지 않다. 부패를 되돌릴 수 있어야 하는 것이다.
이것이 바로 이 책의 주제다. 즉, 이 책은 부패를 되돌리는 방법을 다룬다. 복잡하게 얽힌 불명료한 시스템을 단계별로 점진적인 방법을 통해 단순하면서 잘 구조화돼 있고 훌륭하게 설계된 시스템으로 변모시키는 방법을 알려준다.
다만, 지나친 흥분은 가라앉히자. 부패를 되돌리는 것은 쉽지 않으며 단기간에 가능하지도 않다. 이 책에서 제시하는 기술이나 패턴, 도구들은 효과적이지만 그만큼 많은 노력과 시간, 인내, 주의를 요구한다. 이 책은 결코 만병통치약을 제시하지 않는다. 하룻밤 사이에 시스템에 쌓인 모든 부패를 되돌리는 방법은 없다. 대신, 여러분이 앞으로의 개발 업무에서 갖춰야 할 원칙과 개념 및 태도, 그리고 품질이 나빠지고 있는 시스템을 점진적으로 개선하는 데 도움이 되는 방법을 설명할 것이다. / 로버트 C. 마틴
이 책에서 다루는 내용
■ 기능 추가, 버그 수정, 설계 개선, 성능 최적화 등의 소프트웨어 변경 기법
■ 레거시 코드를 테스트 하네스 안에 넣는 방법
■ 새로운 문제 발생으로부터 시스템을 보호해주는 테스트 루틴 작성법
■ 자바, C++, C, C# 언어로 작성된 예제를 통해 소개하는 어떤 언어나 플랫폼에도 사용 가능한 기법
■ 코드에서 수정해야 할 부분을 정확히 찾아내는 방법
■ 객체 지향적으로 작성되지 않은 레거시 시스템을 다루는 기법
■ 구조가 모호한 애플리케이션을 다루는 방법
이 책의 구성
1부, ‘코드 변경의 메커니즘’은 소프트웨어 코드를 변경하는 네 가지 이유와 단위 테스트, 레거시 코드를 변경하는 순서, 봉합 모델 등 소프트웨어 변경 기법에 관해 다룬다.
2부, ‘소프트웨어 변경’은 레거시 코드 작업과 관련된 매우 일반적인 질문을 다루고 있으며, 각 장의 제목은 특정한 문제를 가리킨다. 이 때문에 제목이 다소 길어졌지만, 독자들이 필요한 내용을 쉽게 찾는 데 도움이 될 것이다.
2부의 앞뒤로는 도입부에 해당하는 몇 개의 장들(1부, ‘코드 변경의 메커니즘’)과 레거시 코드를 다룰 때 유용한 리팩토링에 관한 내용(3부, ‘의존 관계 제거 기법’)을 배치했다. 도입부의 장들, 특히 4장, ‘봉합 모델’은 꼭 읽길 바란다. 2부에서 사용되는 기법들의 배경지식과 관련 용어들을 설명하기 때문이다. 문맥상 이해되지 않는 용어가 있다면 부록의 ‘용어 사전’을 참조한다.
3부, ‘의존 관계 제거 기법’에서 소개하는 리팩토링 기법들은 테스트 루틴이 없는 상황에서 테스트 수행을 목표로 한다는 점에서 특별하다. 더 많은 선택지를 갖고 레거시 코드를 다루기 위해서라도 3부의 각 장을 읽어볼 것을 권장한다.
목차
목차
- 1부. 코드 변경의 메커니즘
- 1장. 소프트웨어 변경
- 소프트웨어 코드를 변경하는 네 가지 이유
- 기능 추가와 버그 수정
- 설계 개선
- 최적화
- 네 가지 이유의 종합
- 위험한 변경
- 소프트웨어 코드를 변경하는 네 가지 이유
- 2장. 피드백 활용
- 단위 테스트란?
- 상위 수준의 테스트
- 테스트를 통한 코드 보호
- 레거시 코드를 변경하는 순서
- 변경 지점을 식별한다
- 테스트 루틴을 작성할 위치를 찾는다
- 의존 관계를 제거한다
- 테스트 루틴을 작성한다
- 변경 및 리팩토링을 수행한다
- 이후의 내용
- 3장. 감지와 분리
- 협업 클래스 위장하기
- 가짜 객체
- 가짜 객체의 양면성
- 가짜 객체의 핵심
- 모조 객체
- 협업 클래스 위장하기
- 4장. 봉합 모델
- 엄청난 양의 테스트
- 봉합
- 봉합의 종류
- 전처리 봉합
- 링크 봉합
- 객체 봉합
- 5장. 도구
- 리팩토링 자동화 도구
- 모조 객체
- 단위 테스트 하네스
- JUnit
- CppUnitLite
- NUnit
- 기타 xUnit 프레임워크
- 일반적인 테스트 하네스
- FIT
- 피트니스
- 2부. 소프트웨어 변경
- 6장. 고칠 것은 많고 시간은 없고
- 발아 메소드
- 장점과 단점
- 발아 클래스
- 장점과 단점
- 포장 메소드
- 장점과 단점
- 포장 클래스
- 요약
- 발아 메소드
- 7장. 코드 하나 바꾸는 데 왜 이리 오래 걸리지?
- 코드 이해하기
- 지연 시간
- 의존 관계 제거
- 빌드 의존 관계
- 요약
- 8장. 어떻게 기능을 추가할까?
- 테스트 주도 개발
- 실패 테스트 케이스 작성
- 컴파일
- 테스트 통과시키기
- 중복 제거
- 실패 테스트 케이스 작성
- 컴파일
- 테스트 통과시키기
- 중복 제거
- 테스트 실패 케이스 작성
- 컴파일
- 테스트 통과시키기
- 중복 제거
- 차이에 의한 프로그래밍
- 요약
- 테스트 주도 개발
- 9장. 뚝딱! 테스트 하네스에 클래스 제대로 넣기
- 성가신 매개변수
- 숨겨진 의존 관계
- 복잡한 생성자
- 까다로운 전역 의존 관계
- 공포스러운 인클루드 의존 관계
- 양파껍질 매개변수
- 별명을 갖는 매개변수
- 10장. 테스트 하네스에서 이 메소드를 실행할 수 없다
- 숨어있는 메소드
- 언어의 편리한 기능
- 탐지 불가능한 부작용
- 11장. 코드를 변경해야 한다
- 영향 추론
- 전방 추론
- 영향 전파
- 영향 추론을 위한 도구
- 영향 분석을 통한 학습
- 영향 스케치의 단순화
- 12장. 클래스 의존 관계, 반드시 없애야 할까?
- 교차 지점
- 간단한 경우
- 상위 수준의 교차 지점
- 조임 지점을 이용한 설계 판단
- 조임 지점의 함정
- 교차 지점
- 13장. 변경해야 하는데, 어떤 테스트를 작성해야 할지 모르겠다
- 문서화 테스트
- 클래스 문서화
- 정해진 목표가 있는 테스트
- 문서화 테스트를 작성하기 위한 경험칙
- 14장. 나를 미치게 하는 라이브러리 의존 관계
- 15장. 애플리케이션에 API 호출이 너무 많다
- 16장. 변경이 가능할 만큼 코드를 이해하지 못하는 경우
- 노트/스케치
- 표시 나열
- 책임 분리
- 메소드 구조의 이해
- 메소드 추출
- 변경 영향의 이해
- 스크래치 리팩토링
- 미사용 코드 삭제
- 17장. 내 애플리케이션은 뼈대가 약하다
- 시스템의 스토리텔링
- 네이키드 CRC
- 대화 음미
- 18장. 테스트 코드가 방해를 한다
- 클래스 명명 규칙
- 테스트 코드의 배치
- 19장. 내 프로젝트는 객체 지향이 아니다
- 간단한 경우
- 어려운 경우
- 새로운 동작의 추가
- 객체 지향의 장점 이용
- 모든 것이 객체 지향적이다
- 20장. 이 클래스는 너무 비대해서 더 이상 확장하고 싶지 않다
- 책임 파악
- 그 밖의 기법들
- 더 나아가기
- 전략
- 전술
- 클래스 추출을 마친 후
- 21장. 반복되는 동일한 수정, 그만할 수는 없을까?
- 첫 번째 단계
- 첫 번째 단계
- 22장. ‘괴물 메소드’를 변경해야 하는데 테스트 코드를 작성하지 못하겠다
- 괴물 메소드의 다양한 종류
- 불릿 메소드
- 혼잡 메소드
- 리팩토링 자동화 도구를 사용해 괴물 메소드 공략하기
- 수동 리팩토링에 도전
- 감지 변수 도입
- 아는 부분 추출하기
- 의존 관계 이삭줍기
- 메소드 객체 추출
- 전략
- 뼈대 메소드
- 처리 시퀀스 발견
- 우선 현재 클래스 내에서 추출
- 작은 조각 추출
- 추출을 다시 할 각오
- 괴물 메소드의 다양한 종류
- 23장. 기존 동작을 건드리지 않았음을 어떻게 확인할 수 있을까?
- 초집중 모드에서 편집하기
- 단일 목적 편집
- 서명 유지
- 컴파일러 의존
- 짝 프로그래밍
- 짝 프로그래밍
- 24장. 어찌해야 할지 모르겠다. 나아질 것 같지 않아
- 3부 의존 관계 제거 기법
- 25장 의존 관계 제거 기법
- 매개변수 적응
- 메소드 객체 추출
- 정의 완성
- 전역 참조 캡슐화
- 정적 메소드 드러내기
- 호출 추출과 재정의
- 팩토리 메소드 추출과 재정의
- get 메소드 추출과 재정의
- 구현체 추출
- 더 복잡한 예제
- 인터페이스 추출
- 인스턴스 위임 도입
- 정적 set 메소드 도입
- 연결 대체
- 생성자 매개변수화
- 메소드 매개변수화
- 매개변수 원시화
- 특징 끌어올리기
- 의존 관계 밀어 내리기
- 함수를 함수 포인터로 대체
- 전역 참조를 get 메소드로 대체
- 서브클래스화와 메소드 재정의
- 인스턴스 변수 대체
- 템플릿 재정의
- 텍스트 재정의
- 부록. 리팩토링
도서 오류 신고
정오표
정오표
[p.104: 밑에서 3행]
http://fitness.org
->
http://fitnesse.org