레거시 코드 활용 전략 [손대기 두려운 낡은 코드, 안전한 변경과 테스트 기법]
- 원서명Working Effectively with Legacy Code (ISBN 9780131177055)
- 지은이마이클 C. 페더스
- 옮긴이이우영, 고재한
- ISBN : 9788989975922
- 36,000원
- 2008년 10월 22일 펴냄 (절판)
- 페이퍼백 | 516쪽 | 185*235mm
판매처
- 현재 이 도서는 구매할 수 없습니다.
책 소개
[ 소개 ]
레거시 시스템을 효율적으로 관리해 성능, 기능성, 신뢰성, 관리능력을 높이자.
저자 마이클 페더스는 이 책에서 테스트 루틴이 없는 거대한 레거시 코드 베이스로 더 효과적인 작업을 하는 전반적인 전략을 알려준다. 이 책은 유명한 오브젝트 멘토(Object Mentor) 세미나용으로 제작된 자료에 기초해, 수백 명의 개발자들과 기술 관리자들을 멘토링하고 테스터들이 레거시 시스템을 제어하는 데 도움을 준 내용을 기술한 책이다.
[ 이 책에서 다루는 내용 ]
■ 특징 추가, 버그 수정, 설계 개선, 성능 최적화 등 소프트웨어 변경 기법
■ 레거시 코드를 테스트 하니스 안에 넣는 방법
■ 새로운 문제 발생으로부터 시스템을 보호해주는 테스트 루틴 작성법
■ 자바, C++, C, C# 언어로 작성된 예제를 통해 어떤 언어나 플랫폼에도 사용 가능
■ 코드에서 변화시켜야 할 부분을 정확히 찾아내는 방법
■ 객체지향으로 작성하지 않은 레거시 시스템을 다루는 기법
■ 구조가 모호한 응용프로그램을 다루는 방법
그밖에 24가지 의존관계 깨기 기법 등 프로그램 구성 요소로 독립적인 작업을 하거나 안전하게 변경하는 경우에 대해 자세히 설명한다.
[ 추천의 글 ]
이 책 서문에서 저자 마이클 페더스는
“…그러자 다음과 같은 일이 일어났다...”
라는 문장으로 자신이 소프트웨어에 대한 열정을 품기 시작한 때를 설명했다.
“…그러자 다음과 같은 일이 일어났다...”
당신은 이러한 감정을 이해할 수 있는가? 당신은 자신의 인생에 있어서 단 한 순간이라도 “…그러자 다음과 같은 일이 일어났다...”라고 말할 수 있었던 때가 있는가? 인생의 방향을 송두리째 바꿔 놓아 결국 당신이 이 책을 집게 됨으로써 내 서문을 읽게 만든 사건이 한 번이라도 있었는가?
초등학교 6학년 때였다. 당시 나는 과학과 우주 그리고 과학기술에 관련된 모든 것에 관심이 있었다. 내 어머니는 제품 카탈로그를 보시고는 플라스틱 껍데기 안에 든 작은 디지컴(IDigi-Comp I)이라는 컴퓨터 한 대를 주문했다. 40년이 흐른 지금 그때의 작은 컴퓨터는 내 책상 위에서 명예로이 한자리를 차지하고 있다. 그 컴퓨터는 내가 소프트웨어에 끊임없이 열정을 갖게 하는 기폭제가 됐다. 나는 사람들이 지닌 문제들을 컴퓨터를 통해 푸는 게 얼마나 즐거운 일인지 처음으로 어렴풋이 깨닫게 됐다. 당시 내 컴퓨터는 플라스틱 S-R 플립플랍(flip-flop) 3개, 플라스틱 AND 게이트(and-gate) 6개로 이루어진 물건이었으나 그것만으로도 충분했다.
하지만 얼마 가지 않아 기쁨은 곧 사라지고 말았다. 소프트웨어 시스템은 결국 엉망진창이 되어 버린다는 사실 때문이었다. 프로그래머들이 처음에 생각해낸 명료한 설계는 결국 시간이 지남에 따라 상한 고기처럼 부패하게 된다. 우리가 작년에 구축한 시스템은 내년에는 함수와 변수로 뒤엉켜 버린 늪으로 변하고 만다.
왜 이런 일들이 일어날까? 왜 시스템은 부패해 가는 걸까? 왜 시스템은 깨끗한(clean) 상태에 머물러 있지 않을까?
때때로 우리는 고객에게 책임을 돌린다. 고객의 요구사항이 변경됐기 때문이라고도 말한다. 고객의 요구사항이 정확히 반영되고 고객이 반영사항에 만족해 한다면, 설계도 분명히 훌륭할 것이라는 믿음 하나로 우리는 스스로를 위안한다. 요구사항 변경은 고객의 잘못 탓이다.
여기서 중요한 소식을 하나 전하겠다. 요구사항은 반드시 변하게 되어 있다. 요구사항 변경을 수용할 수 없다면 설계가 서투른 탓이다. 변경을 수용하는 설계를 생성해내는 일은 모든 유능한 소프트웨어 개발자에게 있어 영광스러운 일이다.
견고한 설계를 만들어 내는 일은 아주 어려운 문제를 푸는 것처럼 인식된다. 실제로도 이런 작업은 너무나 힘든 탓에 제작된 모든 시스템은 서서히 부패해 결국 망가지는 과정을 겪게 된다. 이 같은 부패는 너무나도 침습력이 강해 우리는 썩은 프로그램에 걸맞은 특별한 이름을 준비했다. 바로 ‘레거시 코드’다.
레거시 코드라는 말은 프로그래머들의 가슴에서 구토를 유발한다. 마치 끈적이는 거머리와 날카로운 침을 가진 날벌레들로 뒤덮인 덤불 천지의 음산한 늪지대를 걸어가는 것과 같은 이미지를 연상시킨다. 또한 암흑, 점액, 고인물, 내장에서 나는 악취를 떠올린다. 프로그래밍에 대한 즐거움은 매우 강렬하지만, 레거시 코드를 다뤄야 하는 고통은 개발자들의 열정을 꺾어 버리고도 남을 만큼 충분히 크다.
누구나 우리가 만들어놓은 코드가 레거시 코드로 전락하지 않도록 방지하는 방법을 다각도로 찾아보려고 노력했다. 그간 많은 저자가 프로그래머들이 시스템을 깨끗하게 유지하는 데 도움을 줄 수 있는 원칙(principles), 패턴(patterns), 실행법(practices)에 대한 책을 다수 저술했다. 하지만 마이클 페더스는 우리들 대다수가 간과한 사항에 대한 통찰력을 갖고 있었다. 예방만으로는 완전할 수 없다. 최고 원칙을 숙지하고 최고 패턴을 사용하며 최선의 실행법을 따르는 가장 잘 훈련된 개발팀에서조차 때때로 작업을 망치는 일이 종종 일어난다. 부패는 계속 쌓여가고 부패를 방지하는 것만으로는 충분하지 않다. 부패를 역전(reverse)시킬 수 있어야만 한다.
이 점이 바로 이 책이 이야기하려는 내용이며 이는 곧 부패를 역전시키는 방법인 셈이다. 이 책은 복잡하게 얽힌 불명료한 시스템을 한 조각씩 단계를 밟아가는 점진적인 방법을 통해 단순하면서 잘 구조화되어 있고 훌륭하게 설계된 시스템으로 변모시키는 방법을 알려준다. 이른바 엔트로피 역전(reversing entropy)에 대한 책이라고 말할 수 있겠다.
여러분이 지나치게 흥분하기 전에 한마디 경고하고 싶다. 부패를 역전시키기는 쉽지 않을 뿐더러 단시간에 수행할 수도 없다. 저자가 이 책에서 제시하는 기법이나 패턴, 도구는 효과적이긴 하지만 여러분의 노력과 시간, 인내, 주의를 요구한다. 이 책은 결코 특효약을 제시하지는 않는다. 하룻밤 사이에 어떻게 시스템에 쌓인 모든 부패를 제거하는지에 대한 방법은 제시되지 않을 것이다. 대신 여러분이 현업에 종사하는 데 있어서 갖춰야 할 원칙과 개념, 그리고 태도에 대해 이야기할 것이다. 결국, 성능이 저하되고 있는 시스템을 서서히 향상되는 시스템으로 반전시키는 데 도움을 줄 것이다.
목차
목차
- 1부 워밍업: 코드 변경 원리를 이해하라
- | 1장 | 소프트웨어 변경 ● 29
- 소프트웨어를 수정하는 네 가지 이유 ● 29
- 위험한 변경 ● 35
- | 2장 | 효과적인 피드백 활용 ● 37
- 단위테스트란? ● 40
- 상위단계 테스트 ● 44
- 테스트 덮개 ● 44
- 레거시 코드 변경 알고리즘 ● 48
- | 3장 | 감지와 분리 ● 51
- 협력자 속이기 ● 53
- 협력자 속이기 ● 53
- | 4장 | 봉합 모델 ● 61
- 엄청난 양의 텍스트 ● 61
- 봉합 ● 62
- 봉합의 종류 ● 66
- | 5장 | 레거시 코드를 위한 도구 ● 83
- 자동화된 리팩토링 도구 ● 83
- 모조 객체 ● 86
- 단위테스트 하니스 ● 86
- 일반적인 테스트 하니스 ● 93
- 2부 본격적인 소프트웨어 변경: 코드 이렇게 고치자
- | 6장 | 고칠 건 많고 시간은 없고 ● 97
- 발아 메소드 ● 100
- 발아 클래스 ● 104
- 포장 메소드 ● 109
- 포장 클래스 ● 114
- 요약 ● 120
- | 7장 | 코드 하나 바꾸는 데 왜 이리 오래 걸리지? ● 121
- 상황 이해 ● 121
- 시차 ● 122
- 의존관계 깨기 ● 124
- 요약 ● 130
- | 8장 | 특징, 어떻게 추가할까? ● 131
- 테스트 주도 개발 ● 132
- 비교를 통한 프로그래밍 ● 140
- 요약 ● 152
- | 9장 | 뚝딱! 테스트 하니스에 클래스 제대로 넣기 ● 153
- 성가신 매개변수의 경우 ● 153
- 숨은 의존관계인 경우 ● 162
- 생성 블랍인 경우 ● 165
- 성가신 전역 의존관계인 경우 ● 168
- 끔찍한 인클루드 의존관계인 경우 ● 179
- 양파 매개변수인 경우 ● 184
- 별칭 붙은 매개변수인 경우 ● 187
- | 10장 | 테스트 하니스에서 실행할 수 없는 메소드 ● 191
- 숨은 메소드인 경우 ● 192
- 도움이 되는 언어 특징인 경우 ● 196
- 탐지 불가능한 부작용인 경우 ● 200
- | 11장 | 코드 변경 과정에서 꼭 테스트해야 할 메소드 ● 209
- 효과에 대한 추론 ● 210
- 전방 추론 ● 216
- 효과 전파 ● 222
- 효과 추론을 위한 도구 ● 225
- 효과 분석을 통한 학습 ● 227
- 효과 스케치 단순화 ● 228
- | 12장 | 클래스 의존관계, 반드시 없애야 할까? ● 233
- 차단 지점 기법 ● 234
- 조임 지점을 이용한 설계 판단 ● 242
- 조임 지점 함정 ● 244
- | 13장 | 변경에 필요한 테스트는 뭐가 있을까? ● 245
- 특성화 테스트 ● 246
- 클래스 특성화 ● 250
- 목표 테스트 ● 252
- 특성화 테스트 작성을 위한 휴리스틱 ● 258
- | 14장 | 우릴 미치게 하는 라이브러리 의존관계 ● 259
- | 15장 | 응용프로그램이 모두 API 호출로 이뤄졌다면? ● 261
- | 16장 | 코드를 잘 고치기엔 내가 모르는 2% ● 273
- 노트/스케치 ● 274
- 표식 나열 ● 275
- 스크래치 리팩토링 ● 277
- 미사용 코드 삭제 ● 278
- | 17장 | 뼈대가 약한 내 응용프로그램 ● 279
- 시스템 스토리 말하기 ● 281
- 벌거숭이 CRC ● 286
- 대화 심사 ● 289
- | 18장 | 발목 잡는 테스트 코드 ● 291
- 클래스 명명 관행 ● 291
- 테스트 위치 ● 293
- | 19장 | 객체지향이 아니라서 위험하다고? 그럼 이렇게 고쳐 봐 ● 295
- 쉬운 경우 ● 296
- 어려운 경우 ● 297
- 새로운 동작 추가 ● 302
- 객체지향의 장점 이용 ● 305
- 모두 객체지향적이다 ● 310
- | 20장 | 내 프로젝트 군살 빼기 ● 313
- 책임 찾기 ● 318
- 다른 기법 ● 334
- 더 나아가기 ● 334
- 클래스 추출을 마친 후 ● 338
- | 21장 | 동일 코드의 반복 수정, 그만할 수는 없을까? ● 339
- 첫 번째 단계 ● 343
- 첫 번째 단계 ● 343
- | 22장 | ‘괴물 메소드’와의 혈투, 승부수는 적절한 테스트 루틴 ● 363
- 여러 가지 괴물 메소드 ● 364
- 자동화된 리팩토링 지원으로 괴물 메소드 공략 ● 369
- 수동 리팩토링 도전 ● 372
- 전략 ● 381
- | 23장 | 위반사항을 점검하는 몇 가지 기법 ● 385
- 하이퍼웨어 편집 ● 386
- 단일 목적 편집 ● 387
- 서명 보전 ● 389
- 컴파일러 의존 ● 392
- | 24장 | 무너진 코드의 하늘, 솟아날 구멍이 있을까? ● 397
- 3부 반드시 넘어야 할 산: 코드 변경의 난맥, 의존관계를 극복하라
- | 25장 | 의존관계를 깨는 기법 ● 403
- 매개변수 적응 ● 404
- 메소드 객체 탈출 ● 408
- 정의 완료 ● 416
- 전역 참조 캡슐화 ● 418
- 정적 메소드 드러내기 ● 426
- 호출 추출과 오버라이드 ● 430
- 팩토리 메소드 추출과 오버라이드 ● 432
- 게터 추출과 오버라이드 ● 435
- 구현체 추출 ● 439
- 인터페이스 추출 ● 445
- 인스턴스 위임자 도입 ● 453
- 정적 세터 도입 ● 456
- 연결 대체 ● 463
- 생성자 매개변수화 ● 464
- 메소드 매개변수화 ● 469
- 매개변수 원시화 ● 471
- 특징 끌어올리기 ● 474
- 의존관계 밀어내리기 ● 479
- 함수를 함수포인터로 대체 ● 483
- 전역 참조를 게터로 대체 ● 487
- 메소드 하위클래스화와 오버라이드 ● 490
- 인스턴스 변수 대체 ● 493
- 템플릿 재정의 ● 498
- 텍스트 재정의 ● 502
- | 부록 | 리팩토링 ● 504
관련 블로그 글
개발자들의 계륵 "레거시 코드", 이젠 정복하세요!
손대기 두려운 낡은 코드, 안전한 변경과 테스트 기법
마이클 페더스 지음 | 이우영 고재한 옮김 |
516쪽 | 36,000원 | 2008년 10월 22일 출간예정
legacy 〔〕
n. (pl. -cies)
1 [法] (유언에 의한 동산의) 유증(遺贈); 유산.
2 (조상이나 선인의) 유산, 유물; 과거의 유산.
출처: NEWACE(금성판 뉴에이스)사전
레거시 코드.
버리자니 아깝고, 손대자니 두려운 코드.
뭔가를 만들어 그 기능성이 떨어지지 않도록 유지보수하는 일은 어떤 산업 분야에서건 매우 중요한 일입니다. 게다가 소프트웨어에서 생명줄과도 같은 코드를 유지보수하는 일은 꽤나 중요한 일입니다만, 대부분 레거시 코드는 개발자들에게는 계륵(鷄肋)과도 같은 존재를 넘어 두려움의 대상이기도 합니다.
처음 시스템을 구축할 때의 업무환경을 그대로 유지하기란 사실 불가능한 일입니다. 결국 그럭저럭 돌아가고 있는 소프트웨어에 불가피하게 손을 대야만 하는 일이 필연적으로 생기게 마련이죠. 이때 소스코드도 없고 디컴파일도 불가능해 유지보수는커녕 정체파악도 불가능한 블랙박스가 되어버렸다면 이건 그야말로 진퇴양난 & 초난감 사태가 아닐 수 없습니다. 그런데 다행히 소스코드가 있으면 좀 나을까요? 기능 추가나 리팩토링을 하기 위해서는 테스트가 필수입니다. 그런데 테스트 가능성까지 제로인 경우에는 도대체 어디서부터 어떻게 손을 대야 할까요?
저자는 다년간 오브젝트 멘토 사에서 활동하면서 수많은 고객의 레거시 시스템을 보완하고 유지보수하고 테스트하고 제어하면서 쌓아온 다양한 경험에 기초해 이 책을 집필했습니다. 자바, C, C++로 저자가 직접 작성한 실제 사례 코드는 개발자들의 이해도를 높이는 데 큰 도움이 됩니다.
백문이 불여일견. 이 책에서 다루는 내용은 목차를 한번 훑어보면 가장 이해가 빠르실 듯합니다. 이 책 또한 3부로 나뉘어 1부에서는 소프트웨어 변경 전에 코드 변경 원리를 이해하는 워밍업 단계를 거칩니다. 2부에서는 이 책의 핵심 부분으로서 개발자들이 가장 많이 접하는 실제 코드 수정 사례를 보여주고, 3부에서는 레거시 코드 재활용을 하게 되면 필연적으로 발생하는 골치아픈 문제인 코드간의 얽히고 설킨 의존관계를 깨는 24가지 기법을 상세하게 설명합니다.
1부. 워밍업: 코드 변경 원리를 이해하라
1장. 소프트웨어 변경
2장. 효과적인 피드백 활용
3장. 감지와 분리
4장. 봉합 모델
5장. 레거시 코드를 위한 도구
2부. 본격적인 소프트웨어 변경: 코드 이렇게 고치자
6장. 고칠 건 많고 시간은 없고...
7장. 코드 하나 바꾸는 데 왜 이리 오래 걸리지?
8장. 특징, 어떻게 추가할까?
9장. 뚝딱! 테스트 하니스에 클래스 제대로 넣기
10장. 테스트 하니스에서 실행할 수 없는 메소드
11장. 코드 변경 과정에서 꼭 테스트해야 할 메소드
12장. 클래스 의존관계, 반드시 없애야 할까?
13장. 변경에 필요한 테스트는 뭐가 있을까?
14장. 우릴 미치게 하는 라이브러리 의존관계
15장. 응용프로그램이 모두 API 호출로 이뤄졌다면?
16장. 코드를 잘 고치기엔 내가 모르는 2%
17장. 뼈대가 약한 내 응용프로그램
18장. 발목 잡는 테스트 코드
19장. 객체지향이 아니라서 위험하다고? 그럼 이렇게 고쳐 봐!
20장. 내 프로젝트 군살 빼기
21장. 동일 코드의 반복 수정, 그만할 수는 없을까?
22장. '괴물 메소드'와의 혈투, 승부수는 적절한 테스트 루틴
23장. 위반사항을 점검하는 몇 가지 기법
24장. 무너진 코드의 하늘, 솟아날 구멍이 있을까?
3부. 반드시 넘어야 할 산: 코드 변경의 난맥, 의존관계를 극복하라
25장. 의존관계를 깨는 기법
부록. 리팩토링
왠지 뭔가 한줄 한줄 헤드카피 같은 목차를 보시면 느끼셨겠지만, 저자 스스로 다양한 이론을 만들어 노하우를 공개한 책 답게 새롭게 등장하는 용어도 참 많습니다. 그만큼 용어 선정부터 번역, 편집까지 정말(!) 쉽지 않은 책이었습니다. 얼마 전 만난 역자분과도 오랜만의 회포(?)를 풀었을 만큼 긴 시간을 들인 이 책을 번역하느라 고생하신 이우영님과 고재한님 정말 고생 많으셨습니다. 이 책에 엮인(!) 분들이 한둘이 아닙니다. 허모님, 정모님, 황우님. 기타 등등. 그간 마음 고생 참 많으셨죠? ^^; 책 나오면 그 순간이 끝이 아니라 저희들은 독자분의 반응을 살피기까지 계속 마음을 졸여야 하는데요. 책이 끝나고 좋은 평 받게 되면 우리끼리라도 맥주 한잔씩으로 회포를 풀어야 하지 않을까 싶습니다. -0- 아함~
참, 마지막으로 이 책과 함께 읽으면 정말 좋은 책 두 권을 소개드려요.
바로 『켄트 벡의 구현 패턴: 읽기 쉬운 코드를 작성하는 77가지 자바 코딩 비법』과 『엔터프라이즈급 애자일 방법론: 프로젝트 규모 확장에 따른 애자일 기법과 사례』입니다. 저자는 읽기 쉽고 이해하기 쉬운 코드 명명법 등과, 테스트 주도 개발 등 실용적인 애자일 방법론에 대해서도 설파를 합니다. 이 책들의 많은 내용이 서로 연관성을 지니고 있습니다. 이 책 세 권으로 이제 레거시 코드가 더는 두려운 존재가 아닌, 진귀한 보화가 가득한 보물창고로 거듭나길 바라겠습니다. 오늘도 에이콘은 독자 여러분의 삽질과 시간 낭비를 최전선에서 온몸으로 막아드리겠습니다. 열공하세요. ^^/
+ 추가
자고 일어나니 세상이 바뀌어있더라는 말처럼, 밤샘하다가 쓴 글인데 잠깐 눈붙이고 나왔더니 이렇게 여러 분들이 댓글과 트랙백으로 뜨겁게 성원해주셨네요. 우와~ 정말 정말 감사합니다. 저희는 지금 모처에서 마무리 잘 하고 있습니다. 일주일만 기다려주세요. :)
마지막으로 독자분들의 편의를 위해 친절한 링크 알려드려야죠. ^^
이 책은 지금 YES24, 강컴, 교보문고, 알라딘, 인터파크 등에서 예약판매중입니다.
여러분의 사랑이 각 서점까지 쭈우우욱 이어지길 기대해보며!
크리에이티브 커먼즈 라이센스 이 저작물은 크리에이티브 커먼즈 코리아 저작자표시 2.0 대한민국 라이센스에 따라 이용하실 수 있습니다.
도서 오류 신고
정오표
정오표
[ p64 박스 아래로 3행 ]
RostReceiveError는 → PostReceiveError는
[ p77 첫 번째 문장 ]
이 코드에서는 ~ 사용했다. → 이 코드에서는 buildMartSheet 메소드에서 cell을 생성한 후 사용했다.
[ p128 아래에서 5행 ]
AddOpprotunityFormHandler → AddOpportunityFormHandler
[ p132 '테스트 주도 개발' 절 3행 ]
부분을 푸는 데 도움이 되는 한 방법을 구상한다. 그리고 그 방법에 대한
→ 부분을 푸는 데 도움이 되는 한 메소드를 구상한다. 그리고 그 메소드에 대한
[ p132 '테스트 주도 개발' 절 4행 ]
기존에 그런 방법이 없고 → 아직 메소드가 만들어지지는 않았으나
[ p155 박스 아래로 1행 ]
이 테스트는 구조테스트이다. 구조테스트는 → 이 테스트는 생성자 테스트이다. 생성자 테스트는
[ p155 박스 아래로 7행 ]
디폴트 구조 → 기본 생성자(default constructor)
[ p156 아래에서 2행 ]
제공하는 방법을 살펴보자 → 제공하는 메소드를 살펴보자
[ p157 1~3행 ]
그것은 ~ 집합처럼 보인다.
→ 여기서 RGHConnection은, RFDIReportFor나 ACTIOReportFor 등 비즈니스 중심 메소드뿐만 아니라 connect, disconnect, retry 메소드 등 연결을 구성하는 기전을 다루는 메소드들의 집합을 가지고 있는 것처럼 보인다.
[ p157 3행 ]
CreditValidator에 새로운 방법을 → CreditValidator에 새로운 메소드를
[ p157 4행 ]
RFIDReporterFor → RFDIReportFor
[ p157 12행 ]
가짜 클래스를 만듬으로써 → 가짜 클래스를 만듦으로써
[ p159 박스 안 2행 ]
테스트 코드는 생산 코드의 표준처럼 → 테스트 코드는 제작 코드(production code)의 표준처럼
[ p167 아래에서 5행 ]
하지만 제작 코드에서 파기 방법은 사용하지 말아야 한다. 다른 자원을 관리하는 것을 파기하는 객체가 있다면
→ 하지만 제작 코드에서 계승 메소드는 사용하지 말아야 한다. 다른 자원을 관리하는 것을 계승하는 객체가 있다면
[ p168 1행 ]
이제 우리는 파기 방법을 → 이제 우리는 계승 메소드를
[ p392 아래에서 2행 ]
카달로그 → 카탈로그
[ p442 아래에서 3행 ]
생성 코드 구현체임을 알린다. → 제작 코드 구현체임을 알린다.
2015-05-21
p155 17행
클래스에는 하나의 구조만 → 클래스에는 하나의 생성자만