Skip to content

working effectively with legacy code errata

ohyecloudy edited this page May 5, 2013 · 1 revision

working effectively with legacy code errata

물론 여기에 있는 번역도 틀릴 수 있습니다.

감사의 글

  • 제 삼촌 마틴 - 7
    • '''엉클 밥''', 로버트 마틴
    • 엉클 밥은 로버트 마틴의 별명, 저자의 삼촌이 아님
  • 중요하지 않은 사람으로 부터 비판적인 것을 분리시키는 일 - 7
    • 중요한 것과 사소한 것을 분리하기

저자 서문

  • 응. 지금 레거시 코드를 작성하는 중이야 - 9
    • 컨설팅하러 와서 보니까, 다들 레거시 코드만 만들고 앉아있어
    • 친구가 레거시 코드를 작성 하는게 아님
  • 레거시 코드에서는 몇단계를 거치면 다다르게 되는 것이다 - 12
    • 레거시 코드에서는 전혀 별개의 과정을 거쳐야 좋은 디자인에 다다른다
    • but in legacy code, it is something that we arrive at in discrete steps.

1장. 소프트웨어 변경

  • 만약 담당부서 사람들이 변경하고 싶다는 의사를 철회한다면, 우리는 벌써 이 일을 끝냈을 것이다 - 30
    • 그 사람들이 마음을 자꾸 바꿔먹지만 않았어도, 벌써 일을 끝냈을 것이다
    • 잦은 요구사항 변경으로 일정이 늦어지고 있다는 의미
  • 사람들이 작업할 때는 새로운 특징을 추가하건, 혹은 버그를 수정하건 간에 우리는 끊임없이 바꿀 수 있으나 이는 단지 코드나 다른 인공물을 변화시키는 것에 국한된다 - 30
    • 사람들 끼리는 기능추가로 부르든 오류수정으로 부르든 언제든 바꿔 부를 수 있지만, 이런 작업들은 사람에 관련된 작업이 아니라 소스코드와 산출물을 변경하는 작업이다
    • At the people level, we can go back and forth endlessly about whether we are adding features or fixing bugs, but it is all just changing code and other artifacts
  • 동작은 소프트웨어에 있어서 가장 중요한 요소로 사용자는 바로 이 동작을 따르게 된다 - 30
    • 동작은 소프트웨어에 있어서 가장 중요한 요소로, 사용자는 바로 이 동작을 따르게 된다
    • 쉼표 추가. 원문은 두 문장인데 한 문장으로 만들었으니, 쉼표를 추가하자.
  • 반대로 그들이 사용하고 있는 동작을 변경하거나 삭제하면 버그가 생길 수도 있으므로 - 30
    • 버그 '''때문에''' 잘 쓰고 있던 동작이 바뀌거나 사라진다면
  • 우리가 만일 코드(HTML과 같은 코드)를 수정해야 한다면 동작까지 변경시킬 수 있다 - 31
    • 코드(HTML도 코드로 '''취급'''한다)를 수정했다면 동작도 변경 됐다고 '''볼 수 있다'''
  • 어떤 조건을 위반 했는지를 - 35
    • 뭔가 '''망가트리지''' 않았는지를
  • 위반이 아니면 고치지도 말라 - 35
    • '''고장'''나지 않았으면 고치지 마라

2장. 효과적인 피드백 활용

  • 나는 이 원인들을 '편집하고 기도하기' - 37
    • 나는 이 '''방법들을''' '편집하고 기도하기'
  • 덮고 수정하기 - 37
    • 감싸고 수정하기
    • cover - 덮다, 감싸다, 보호하다, 엄호하다.
    • 감싸서 보호한다는 의미
  • 계획을 세우고 - 37
    • 계획을 '''주의깊게''' 세우고
  • 계획에 반하는 사항이 - 37
    • 뭔가 망가트리지 않았는지
  • 개인 시간을 투자해서라도 - 37
    • '''추가''' 시간을 투자해서라도
  • 여러분이 주의를 기울이면 표면적으로 여러분이 바라는 목적지로 인도해줄 것이다 - 37
    • 가장 중요한 핵심 바로 그곳에 "주의"를 기울여야 한다
    • The "care" that you take is right there at the forefront
  • 하지만 이렇게 얻는 피드백을 통해 우리는 좀더 꼼꼼히 - 38
    • 같은 양의 주의를 기울이면서도, 피드백을 함께 활용하면, 우리는 좀더 꼼꼼히
    • We still apply the same care, but with the feedback we get, we are able to make changes more carefully
    • 문장 일부분 번역 빼먹음 - We still apply the same care,
  • 테스트 자체가 좋은 목적일 수도 있고 - 38
    • 물론 그것만으로도 훌륭한 목표지만,
    • 그것은 앞 문장을 의미 - "정확성을 보여주기 위한 테스트"
  • 적용 범위 - 42
    • 커버리지(coverage)
    • "적용 범위"는 의미가 와닿지 않는다. 적당한 번역은 떠오르지 않음.
  • 우리가 좀더 자주 테스트 루틴을 돌릴 경우 오류 지역화에 빠질 우려가 있다는 것이다 - 42
    • 테스트를 자주 돌려야만 오류를 지역화 할 수 있는데,
    • 오류 지역화는 좋은것이다.
    • 대규모 테스트는 시간이 많이 들어 자주 돌릴 수 없어서 좌절하게 된다는 의미
  • 테스트 루틴에는 연속되는 부분이 있게 마련이다 - 42
    • 보통은, 연속체가 있기 마련이다.
    • Naturally, there is a continuum
    • continuum - 다른 여러 클래스를 사용하는 덩치 큰 클래스를 "연속체"라고 이름 붙인 듯 함
  • 시간이 1/100로 줄어든다면 - 43
    • 시간이 1/100'''초'''로 줄어든다면
  • 테스트 덮개 - 44
    • 테스트로 감싸기(Test Coverings)
  • 이것을 생성하는 것은 매우 쉬운 일이다 - 45
    • 이것을 생성하는게 쉬울까?
    • How easy will it be to create one of those?
    • 쉽지 않고 오히려 어렵다는 의미
  • 우리는 서블릿을 매개변수로 받지 않도록 코드를 수정할 수 있다 - 45
    • '''경우에 따라''' 서블릿을 매개변수로 받지 않도록 코드를 수정할 수'''도''' 있다
    • 뒷 문장에 나오는 조건을 만족할 경우에 수정 가능 하다는 의미
  • 제자리 - 46
    • 적절한 자리에
    • in place - 적절한 자리에, 적소에
  • 침습성(스며들어 젖는 성질) - 47
    • 침습적('''공격적이라 해가되는''')
  • 덜 보수적이라면 그 부분을 즉시 고칠 것이다 - 48
    • 덜 보수적이라면 그 부분을 ''' 별 생각없이 바로''' 고칠 것이다
  • '''4줄 삭제'''
    • 이렇게 하면 더 이상 서블릿을 받지 ... 확인하려면 정확한 테스트가 필요하다.
    • 이 내용은 45p 그림 윗부분에 있는 내용이다. 글자는 조금 다르지만 내용은 같다. 삭제하자.
    • 추측하면 copy & paste 실수로 이전 페이지 내용이 엉뚱한 곳에 틀어박혀 있는 것이다.
    • c&p는 코딩할때만 합시다.
  • 하지만 이것은 그 위험도에 따라 다를 수 있다 - 47
    • 가능하지만, 위험도가 얼마나 되는지 따져봐야 한다.
    • We can do that, but it depends upon how much risk is involved
    • 문장 일부분 번역 빼먹음 - We can do that,
  • 오류가 큰 문제이거나 일상적이라면 경우에 따라 알맞은 대응을 해야 할 것이다 - 47
    • 오류가 크게 문제가 될 때면, 보통의 경우 오류는 큰 문제인데, 그럴때는 보수적으로 신중해져야 한다.
    • When errors are a big deal, and they usually are, it pays to be conservative.
  • 레거시 코드에서 하루하루의 목표는 변경 자체가 아니라 변경시키는 행위이다. 각 프로그래밍 에피소드의 - 48
    • 레거시 코드에서 하루하루의 목표는 변경이다. 하지만, 변경만으로 끝나서는 안된다. 우리는 기능적 변경을 함으로써 제품에 가치를 추가하는 동시에 테스트에 보호받는 부분이 더 많아지도록 시스템을 고쳐야 한다.
    • The day-to-day goal in legacy code is to make changes, but not just any changes. We want to make functional changes that deliver value while bringing more of the system under test.
    • 문장 하나를 완전히 빼먹음.
    • 어색한 부분이 발견되면 원문을 참고하면 되지만, 문장을 아예 빼먹는건 답이 없다.
  • 혹 그런 기법들을 사용하길 원한다면 관련 서적을 참고하길 바란다 - 50
    • 그런 기법들을 사용할 기회가 오면, 반드시 적용해 보길 '''적극 추천'''한다
  • 설계를 어떻게 하면 잘 하는지를 보여줄 것이다 - 50
    • 어떻게 하면 '''더 나은 설계로 개선하는지''' 보여줄 것이다
  • 이때의 잘 이뤄진 설계는 문맥 종속적이고 종종 이전 설계보다 몇 개의 관리 가능한 단계를 더 가지게 된다 - 50
    • "더 나은"이란 의미는 상황에 따라 다른데 이전 설계보다 운영 개선하기가 몇 단계 정도 쉬워졌다는 것을 의미할 때가 많다.
    • where "better" is context dependent and often simply a few steps more maintainable than the design was before.

3장. 감지와 분리

  • 감지: 언제 코드가 계산하는 값들에 접근할 수 없는지를 감지하기 위해 의존관계를 제거한다 - 52
    • 탐지 확보 - 코드가 변경하는 값에 접근 하지 못할때, 탐지하기 위해 의존관계를 깨트린다
    • Sensing - We break dependencies to sense when we can't access values our code computes
    • Sensing 과 sense 구별하는게 좋지 않을까?
  • 분리: 언제 코드를 테스트 하니스에 넣어 실행할 수 없게 되는지를 구분하기 위해 의존관계를 제거한다 - 52
    • 분리 확보 - 테스트 하니스에 넣어 실행할 코드 조각을 얻지 못할때, 분리하기 위해 의존관계를 깨트린다
    • Separation - We break dependencies to separate when we can't even get a piece of code into a test harness to run
  • 하지만 테스트할 때는 sale 클래스가 객체를 FakeDisplay로 여겨야 한다 - 58
    • 하지만 테스트 코드에서는 FakeDisplay 객체로 취급해야 한다

4장. 봉합 모델

  • 봉합
  • 봉합 : 봉합(seams)은 프로그램 안에서 동작을 변화시킬 수 있는 위치를 말한다. 이때 동작을 변화시키기 위해 코드를 편집할 필요는 없다. - 64
    • 이음매(seams)는 그 위치의 코드를 변경시키지 않으면서 프로그램의 동작을 변화시키는 위치를 말한다.
  • 자, 그러면 CAsyncSSlRec 클래스를 하위클래스하고 PostReceive 메소드에 덮어쓰면 어떨까? - 64
    • 자, 그러면 CAsyncSSlRec 클래스를 하위클래스하고 PostReceive 메소드를 오버라이드(override)하면 어떨까?
    • override를 덮어쓴다고 번역하기 보다 영어 용어를 그대로 사용하는게 이해가 더 쉽다.
  • 불명확한 버그를 숨기기 위한 매크로를 만들기도 하는데 이런 일은 쉬운일에 속한다 - 68
    • 매크로를 작성할때 엄청나게 '''찾기 어려운''' 버그를 만들기 쉽다
  • 참조를 분해할 때 어떤 방법을 사용하든 간에 - 71
    • 사용중인 언어가 참조를 '''해석'''하는데 어떤 방식을 사용하든 간에
  • 전처리 봉합과 연결 봉합은 의존관계에 침습성을 가지고 있다. 따라서 대안이 없는 경우를 감안해 이를 남겨 놓을 것이다 - 81
    • 전처리 이음매와 연결 이음매는 일단 사용을 미뤄두고, 의존관계가 '''널리 퍼져''' 더 나은 대안이 없는 경우에 사용한다

5장. 레거시 코드를 위한 도구

  • 이런 종류의 작업은 좀 더 정확히는 통합 테스트를 위한 프레임워크와 적합성 영역이다 - 93
    • 이런 종류의 작업은 '''FIT와 Fitness의 영역'''이라 보는게 더 적절하다

6장. 고칠 건 많고 시간은 없고

  • 날짜를 게시하고 새로운 항목을 추가하기 전에는 그 새 항목이 - 100
    • 날짜를 게시하고 새로운 항목을 추가하기 전에 그 새 항목이 ('는' 삭제)
  • 침투성 - 101, 109
    • 침습적
  • 여기서는 지불을 기록할 필요가 있는 한 부분에 LogPayDispatcher 클래스를 생성했다 - 118
    • 이제 지불을 기록해야할 곳에서 LogPayDispatcher 클래스를 '''생성할 수 있다'''

7장. 코드 하나 바꾸는 데 왜 이리 오래 걸리지?

  • 그림에는 나타나 있지 않지만 그 두 클래스가 서로 종속되어 있는 경우라면 더 좋다고 할 수 있다 - 126
    • 두 클래스 모두 그림에 나오지 않은 '''또 다른 클래스들에 의존'''하고 있을 가능성이 크다
  • 다음에 ConsultantSchedulerDBImpl, AddOpportunityFormHandler를 수정할 때는 재컴파일할 필요가 없다 - 127
    • 이제 ConsultantSchedulerDBImpl를 수정해도, AddOpportunityFormHandler는 재컴파일할 필요가 없다

8장. 특징, 어떻게 추가할까?

  • 비교를 통한 프로그래밍 - 140, 148, 151
    • 차이에 의한 프로그래밍(Programming by Difference)
  • 의존관계 - 140, 149 등
    • '''상속'''
  • 하지만 의존관계를 사용한다는 것 자체가 반드시 제자리 의존관계를 유지해야 한다는 뜻은 아니다 - 140
    • 하지만 상속을 사용했을때, 제대로 올바르게 상속을 사용했다고 장담 할 수 없다.
    • But just because we use inheritance initially doesn't mean that we have to keep it in place.
    • 이 문장의 주어는 과연 무엇일까? 이 문장은 과연 깔끔한 영어 문장일까? 미국애들이 볼때 문장구조나 의미가 명확할까?
  • 오버라이딩하는 메소드 안에 있는 현재 오버라이딩하려는 메소드를 호출할 수 있는지 확인한다 - 150
    • 오버라이딩 메소드에서 오버라이드 되는 메소드를 호출할 수 있는지 확인한다
  • 가끔씩 일어나는 추상적인 오버라이드는 - 151
    • 가끔씩 일어나는 '''구체(concrete)''' 오버라이드는

9장. 뚝딱! 테스트 하니스에 클래스 제대로 넣기

  • 코드를 변화시키는 일은 참 어려운 일이지만 멋진 작업이기도 하다 - 153
    • 이는 정말 어렵다
    • This is the hard one
    • 9장 제목의 작업이 어렵다는 의미 (테스트 하니스에 요놈의 클래스를 못 집어넣겠어요!)
  • 테스트 하니스에서 클래스의 구체적 예를 드는 것은 쉬운 일이지만, 불행하게도 얇은 이 책을 통해 제시하기란 결코 쉬운 일이 아니다 - 153
    • 테스트 하니스에서 클래스의 '''인스턴스'''를 만들기가 '''쉽다면''', 이 책은 무척 '''얇아졌을''' 것이다
  • 테스트 하니스는 그 안의 클래스와 함께 쉽게 만들어지지 않는다 - 153
    • 여러 클래스들을 엮어 테스트 하니스를 만들기는 쉽지 않다
    • The test harness won't easily build with the class in it
  • 구조 - 153, ...
    • 생성자(constructor)
  • 그리고 제자리 테스트 안에 둘 필요가 있겠네 - 153
    • 그리고 당연히 테스트 하니스 안에 집어 넣어야지
  • 에이, 이것은 이 클래스 상에 있는 가장 단순한 생성자로 3개의 매개변수를 받는 것 같은데, 생성하기도 어렵지 않겠네 - 154
    • 세상에, 제일 단순한 생성자도 파라미터가 3개나 되네. 하지만, 생성하기가 그렇게 어렵지는 않을거야
  • 단지 방어적인 것이었는지 - 154
    • 단순히 '''방어 심리'''였는지
  • 클라이언트가 유효한 신용을 갖고 있는지 - 154
    • '''고객'''의 신용이 유효한지
  • 클라이언트들이 얼마나 많은 신용을 갖고 있는지를 - 154
    • '''고객'''이 '''어느 정도'''의 신용을 갖고 있는지
  • 우리는 왜 그것이 최상이고 쉬운지(혹은 어려운지)를 알아내기 위해 수 차례 분석했다. 하지만, - 154
    • 생성하기 쉬운지 어려운지 알아내기위해 엄청나게 분석해도 되긴 하지만,
    • 분석하지 말고 그냥 코딩해서 컴파일 에러가 나는지 보라는 의미
  • 구조 - 154, ...
    • 생성(construction)
  • 따라서 이 테스트 하니스에서 이 클래스를 획득하는 것은 다소 쉬워 보이는데 정말 그러할까? - 156
    • 그래서, 테스트 하니스에 이 클래스를 '''생성'''하기는 쉬워보인다. 그렇지 않나?
  • 실제로 그리 빠르지는 않다 - 156
    • 너무 서두르지 마라
  • 서버에 RGHConnections를 구축하는 것은 좋은 생각이 - 156
    • 서버에 RGHConnections '''연결 접속'''을 하는 것은 좋은 생각이
  • 방법 - 156, ...
    • 메소드(method)
  • 그것은 RGHConnections이 연결을 ~~~ 집합처럼 보인다 - 157
    • 여기서 RGHConnection은, RFDIReportFor나 ACTIOReportFor 등 비즈니스 중심 메소드뿐만 아니라 connect, disconnect, retry 메소드 등 연결을 구성하는 기전을 다루는 메소드들의 집합을 가지고 있는 것처럼 보인다
    • 에이콘 공식 정오표 참조
  • 만듬 - 157
    • 만듦
  • 고약하게도 그것들이 원할때마다 누구나 설정할 수 있는 공개된 변수가 존재한다 - 158
    • 더 고약한 사실은, 변수가 public이라 아무나 값을 변경할 수 있다는 점이다
  • 규칙을 클래스와 달라 테스트를 가능하게 한다 - 158
    • 클래스를 테스트 가능하게 만들때 적용하는 규칙은 기존의 코딩 규칙과 다르다
  • 제작 코드 - 158, ...
    • '''제품''' 코드(production code)
  • (문장누락)
    • 책을 덮어버리진 않으셨겠죠?
    • Are you still there?
  • 그렇다면 시스템 안에서는 항상 그 작업이 수행되겠군 - 159
    • 우리가 맨날 하는 짓이군
    • 기존 시스템이 엉망이라 파라미터에 null을 넘기는 짓을 자주 한다는 의미
  • 실제로 하나의 객체를 갖는 동작이 필요하다면, 당신은 그 지점에서 객체 하나를 생성한 후 - 160
    • 동작하는데 정말로 객체가 필요하다면, '''그때 가서''' 객체를 하나 생성한 후
  • 선택할 수 있다면 제작 코드에서는 - 160
    • 다른 선택의 여지가 없는 경우가 아니라면 제품 코드에서는
  • 어떤 라이브러리들은 그렇게 하도록 기대하지만, 차라리 새로운 코드를 작업하는 것이 더 효과적이다 - 160
    • null 값을 넘겨야하는 라이브러리도 있다는 사실을 알고 있지만, 새로운 코드를 작성할 때면 '''더 나은 대안'''을 찾아야 한다
  • 제족 코드에서 널을 사용하려 한다면 널이 되돌아오고 널을 전달시킬 곳을 찾고, 다른 프로토콜을 고려하자 - 160
    • 제품코드에서 널을 사용하고자 하는 유혹이 느껴진다면, 널을 리턴하거나 전달하는 곳을 찾은 다음, 다른 방식(protocol)의 사용을 고려해보자
  • 위 코드는 클래스의 생성자 코드 중 일부분이다 - 162
    • 이제 클래스 생성자의 일부를 살펴보자
  • 커서를 만들기 위해 사용한 코드는 모두 클래스 외부로 옮길 수 있다 - 166
    • 커서를 만드는데 사용한 코드를 모두 클래스 밖으로 옮기려 '''시도해 볼 수도''' 있다
  • 그러나 테스할 곳이 없다면 이는 안전하지 못하고, - 166
    • 그러나 '''적절한(in place) 테스트'''가 없다면, 이는 안전하지 못하고
  • 파기 - 167, ...
    • 갈아치움(supersede)
  • 제작 코드에서 파기 방법은 - 167
    • '''제품 코드'''에서 '''갈아치움 메소드'''는
  • 다른 자원을 관리하는 것을 파기하는 객체가 있다면 이는 심각한 자원 문제를 일으킬 수 있다 - 167
    • 우리가 '''갈아치운''' 객체가 다른 리소스들을 관리했다면, 심각한 리소스 문제가 생길지도 모른다
  • 우리는 느낄 필요가 있기에, - 168
    • 우리는 '''탐지(sense)'''해야 하기 때문에,

진행중

  • 시밤쾅! 9장 번역 개판

10장. 테스트 하니스에서 실행할 수 없는 메소드

  • 진행중

11장. 코드 변경 과정에서 꼭 테스트해야 할 메소드

  • 진행중

12장. 클래스 의존관계, 반드시 없애야 할까?

  • 시밤쾅! 12장 번역 개판

13장. 변경에 필요한 테스트는 뭐가 있을까?

  • 진행중

14장. 우릴 미치게 하는 라이브러리 의존관계

  • 좋은 코드는 제작이나 테스트 환경 내에서 수행된다는 - 260
    • 좋은 코드는 제작 환경과 테스트 환경 '''양쪽 모두에서''' 실행된다는

15장. 응용프로그램이 모두 API 호출로 이뤄졌다면?

  • 진행중

참고

acorn 출판사가 관리하고 있는 레거시 코드 활용 전략/정오표

Clone this wiki locally