"변경하지 않음"으로 표시된 코드를 리팩터링해야합니까?


148

나는 꽤 큰 코드베이스를 다루고 있으며 기존 코드를 리팩토링하는 데 몇 달이 걸렸습니다. 리 팩터 프로세스는 곧 제품에 많은 새로운 기능을 추가해야하므로 이제는 더 이상 다른 기능을 중단하지 않고 기능을 추가 할 수 없기 때문에 리팩터링 프로세스가 필요합니다. 요컨대, 많은 사람들이 그들의 경력에서 본 지저분한, 거대하고 버그가 많은 코드.

리팩토링 중에 때때로 다음과 같은 주석이있는 클래스, 메소드 또는 코드 줄이 발생합니다.

모듈 A가 시간을 할애하도록 시간 초과를 설정했습니다. 이와 같은 시간이 지정되지 않으면 중단됩니다.

또는

이것을 바꾸지 마십시오. 날 믿어 라, 당신은 일을 깰 것이다.

또는

setTimeout을 사용하는 것은 좋은 습관이 아니라는 것을 알고 있지만이 경우에는 사용해야합니다.

내 질문은 : 저자로부터 그러한 경고가 발생할 때 코드를 리팩터링해야합니까 (저는 저자와 연락 할 수 없습니다)?


157
축하합니다! 이제 코드 작성자입니다.

12
해야 할 일과 실제로하는 일을 모두 알기 전까지는 문제를 해결할 수 없습니다 (변경의 전체 결과를 이해하려면 후자를 알아야합니다). 작업 # 1을 리팩토링해야합니다. 그렇지 않으면 변경 될 때마다 상황이 악화 될 것입니다. 당신이 물어봐야 할 질문은 그것을하는 방법입니다. 그 질문에는 언어와 플랫폼 의존성이 상당히 있습니다. 예 : stackoverflow.com/questions/3099794/finding-threading-bugs
sdenham

14
@ sdenham의 의견에 후속 : 코드베이스를 실행하는 자동화 된 단위 테스트가 아직없는 경우 AFAICT를 사용하여 "리팩터링 마녀 사냥"에 시간을 낭비하는 대신 이러한 단위 테스트를 만드는 데 시간을 낭비하지 않는 것이 좋습니다. 마음에. 코드 기반 을 철저히 테스트하는 일련의 단위 테스트가 완료되면 코드를 다시 작성해야 할 때 / 사용할 때 코드가 여전히 작동하는지 객관적인 방법으로 알 수 있습니다. 행운을 빕니다.
Bob Jarvis

17
만약 저자가 너무 편집증을 일으켜 누군가가 숨을 쉬면 코드가 깨질 것입니다. 아마도 이미 깨졌으며 정의되지 않은 동작이 현재 원하는 방식으로 작동합니다. 첫 번째는 특히 경쟁 조건이있어서 대부분의 시간 동안 작동하는 것처럼 보입니다. sdenham이 옳습니다. 해야 할 일을 파악하고 그것이 실제로하는 일이라고 가정하지 마십시오.
Ray

7
@Ethan 그렇게 간단하지 않을 수 있습니다. 코드를 변경하면 즉시 눈에 띄지 않는 방식으로 코드가 손상 될 수 있습니다. 때때로이 현재 리 팩터가 그 원인이 될 수 있다는 사실을 잊어 버린 후에 오랫동안 깨지기 때문에, 당신이 가진 모든 것은 신비한 원인을 가진 "새로운"버그입니다. 이다 특히 IT 관련 타이밍 때 가능성이 높습니다.
Paul Brinkley

답변:


225

새로운 기능 개발이 진행될 때 코드베이스의 어떤 부분이 세부적으로 변경 될지 모른 채 "경우에 따라"리팩토링하는 것 같습니다 . 그렇지 않으면 취성 모듈을 리팩터링해야하는지 또는 그대로 두어야하는지 알 수 있습니다.

이것을 직설적으로 말하면 : 이것이 운명 리팩토링 전략 이라고 생각합니다 . 실제로 이익을 얻을 수 있을지 아무도 모르는 회사에 시간과 돈을 투자하고 있으며 작업 코드에 버그를 도입하여 상황을 악화시키는 가장자리에 있습니다.

더 나은 전략은 다음과 같습니다.

  • 위험에 처한 모듈에 자동 테스트 (아마도 단위 테스트가 아니라 통합 테스트)를 추가합니다. 특히 언급 한 취성 모듈은 변경하기 전에 전체 테스트 스위트가 필요합니다.

  • 테스트를 수행하는 데 필요한 비트 만 리팩토링하십시오. 필요한 변경을 최소화하십시오. 테스트에서 버그가 밝혀진 경우를 제외하고는 즉시 예외를 고치십시오 (안전하게 필요한 정도로 리팩터링).

  • 동료들에게 "보이 스카우트 원칙"(일명 "기회 리팩토링" )을 가르치십시오 . 따라서 팀이 새로운 기능을 추가하거나 버그를 수정하기 시작하면 변경해야하는 코드 기반의 부분을 정확하게 개선하고 리팩토링해야합니다. 더 이상은 아닙니다.

  • 팀을위한 Feather의 책 "레거시 코드로 효과적으로 작업하기"사본을 얻으십시오.

따라서 새로운 기능 개발 또는 1 단계에서 추가 한 테스트로 인해 버그가 드러나기 때문에 취성 모듈을 변경하고 리팩토링 해야 할 때가되면, 귀하와 귀하의 팀은 모듈을 리팩터링하고 이러한 경고 설명을 다소 안전하게 무시하십시오.

일부 의견에 대한 답변으로 : 공정하게, 기존 제품의 모듈이 정기적으로 문제의 원인이라고 의심되는 경우, 특히 "만지지 마십시오"라고 표시된 모듈은 의심의 여지가 있습니다. 당신. 해당 프로세스에서 검토, 디버그 및 리팩토링해야합니다 (내가 언급 한 테스트를 지원하지만 반드시 순서대로는 아님). 버그는 변경에 대한 강력한 정당화이며 종종 새로운 기능보다 강력합니다. 그러나 이는 사례 별 결정입니다. "만지지 마십시오"라고 표시된 모듈에서 무언가를 바꾸는 번거 로움이 가치가 있는지 매우 신중하게 확인해야합니다.


70
나는 공감하고 싶은 유혹에 빠지지만 자제 할 것이다. 여러 프로젝트 에서이 사고 방식으로 인해 제품이 훨씬 더 나빠지는 것을 보았습니다. 일단 실패가 발생하면, 종종 실패로 인해 치명적이며 수정하기가 훨씬 더 어렵습니다. 나는 정기적으로 내가보고있는 슬러지를 고치고, 그것이 문제만큼이나 많은 문제를 야기하거나 알려진 문제를 남기지 않는 것처럼 보인다. 그것은 전반적으로 큰 플러스입니다. 그리고 코드는 향후 개발에 더 좋습니다. 시간의 스티치는 9를 절약하지만 무시되는 문제는 악화 될 수 있습니다.
Aaron

98
"모듈 A가 시간을 할애하여 시간을 낼 수 있도록 시간 초과를 설정했습니다.이 시간이 맞지 않으면 깨질 것"이라는 주석이 표시된 코드에 이미 버그 가 있다고 주장합니다 . 버그가 맞지 않는 것은 무승부입니다.
17 of 26

10
@ 17of26 : 반드시 버그는 아닙니다. 때로는 타사 라이브러리를 사용하여 작업 할 때 모든 종류의 "우아함"양보를 수행해야합니다.
whatsisname

30
@ 17of26 : 위험에 처한 모듈에 버그가있는 것으로 의심되는 경우 리팩토링 전에 테스트를 추가하는 것이 더욱 중요합니다. 이러한 테스트에서 버그가 밝혀지면 해당 모듈을 변경해야하므로 즉시 리팩터링해야합니다. 테스트에서 버그가 발견되지 않으면 코드를 그대로 두십시오.
Doc Brown

17
@Aaron : 테스트를 추가하거나 보이 스카우트 원칙을 따르는 것이 제품 품질을 저하시키는 이유를 이해하지 못합니다.
Doc Brown

142

예, 다른 기능을 추가하기 전에 코드를 리팩터링해야합니다.

이와 같은 주석의 문제점은 코드베이스가 실행중인 환경의 특정 상황에 따라 달라진다는 것입니다. 특정 지점에서 프로그래밍 된 시간 초과는 프로그래밍 할 때 실제로 필요할 수 있습니다.

그러나이 방정식을 바꿀 수있는 많은 것들이 있습니다 : 하드웨어 변경, OS 변경, 다른 시스템 구성 요소의 관련없는 변경, 일반적인 데이터 볼륨의 변경, 이름. 오늘날에도 그것이 여전히 필요하거나 여전히 충분하다는 보장은 없습니다 (적절한 회귀 테스트 없이는 보호해야 할 내용의 무결성이 오랫동안 깨졌을 수도 있습니다). 그렇기 때문에 다른 구성 요소를 종료하기 위해 고정 지연을 프로그래밍하는 것은 거의 항상 부정확하며 우연히 만 작동합니다.

귀하의 경우, 귀하는 원래 상황을 알지 못하며 원래 저자에게 물어볼 수도 없습니다. (아마도 적절한 회귀 / 통합 테스트를하지 않았거나 단순히 테스트를 통해 문제가 발생했는지 여부를 알려줄 수 있습니다.)

이것은주의를 기울이지 않고 아무것도 바꾸지 않는 주장처럼 보일 수 있습니다. 그러나 당신은 어쨌든 큰 변화가있을 것이라고 말하면서,이 지점에서 달성되었던 섬세한 균형을 혼란스럽게 할 위험은 이미 존재합니다. 지금 사과 카트를 화나게하는 것이 훨씬 낫습니다. 수행하는 것이 리팩토링 일 때, 문제가 발생하면 리팩토링이되었는지 확인하십시오. 추가 변경을 동시에 할 때까지 기다리는 것보다 확실히하다.


46
여기에 가장 좋은 답변; 너무 나쁜 것은 약자입니다. 위의 답변은 좋은 조언이 아니며 특히 "두 메드"에 중점을 둡니다. 나는 (단지에 대한 ~ 10 ^ 6LOC 가장 큰 작업을 지난 1 년 동안 한 , 기존-EST, 내가 본 aweful 코드 그것의 부분), 그리고 그것이 내가있을 때 내가 보는 기차 난파를 해결하는 습관 만들기 시간은 내가 작업하는 구성 요소의 일부가 아닌 경우에도 마찬가지입니다. 이렇게하면 개발자 팀이 알지 못했던 버그를 발견하고 수정했습니다 (최종 사용자는 아마). 사실 저는 지시를 받았습니다. 결과적으로 제품이 개선됩니다.
Aaron

10
그래도 리팩토링은 아니지만 버그 수정이라고 부릅니다.
Paŭlo Ebermann

7
코드베이스의 디자인을 개선하는 것은 리팩토링입니다. 재 설계에서 수정할 수있는 버그가 밝혀지면 버그를 수정 한 것입니다. 내 요점은 첫 번째는 종종 두 번째로 이어지고 두 번째는 첫 번째없이 매우 어렵다는 것입니다.
Kramii

10
@Aaron 관리 / 개발자 지원을 통해 운이 좋았습니다. 대부분의 환경에서 열악한 디자인과 코드로 인해 알려지고 알려지지 않은 버그는 자연스러운 순서로 받아 들여집니다.
Rudolf Olah

5
@nocomprende 나는 당신이 그 시스템을 테스트 할만큼 충분히 시스템을 이해하지 못한다면, 그 작동 방식을 바꿀 사업이 없다고 주장 할 것이다.
Patrick M

61

내 질문은 : 저자로부터 그러한 경고가 발생할 때 코드를 리 팩터해야합니까?

아니거나 적어도 아직은 아닙니다. 자동화 된 테스트 수준이 매우 낮다는 것을 의미합니다. 안심하고 리팩토링하기 전에 테스트가 필요합니다.

지금은 더 이상 다른 것을 깨지 않고 기능을 추가 할 수 없습니다

지금 당장은 리팩토링이 아닌 안정성 향상에 집중해야합니다. 안정성 향상의 일부로 리팩토링을 수행 할 수도 있지만 안정적인 코드베이스라는 실제 목표를 달성하는 도구입니다.

이것이 기존 코드베이스가 된 것처럼 들리므로 조금 다르게 처리해야합니다.

특성화 테스트를 추가하여 시작하십시오. 사양에 대해 걱정하지 말고 현재 동작에 대한 테스트를 추가하십시오. 이렇게하면 새로운 작업으로 인해 기존 기능이 손상되는 것을 방지 할 수 있습니다.

버그를 수정할 때마다 버그가 수정되었음을 증명하는 테스트 사례를 추가하십시오. 이것은 직접적인 회귀를 방지합니다.

새 기능을 추가 할 때 새 기능이 의도 한대로 작동하는지 최소한 몇 가지 기본 테스트를 추가하십시오.

"레거시 코드로 효과적으로 작업하기"의 사본이 있습니까?

기존 코드를 리팩토링하는 데 몇 달이 걸렸습니다.

테스트 범위를 시작하여 시작하십시오. 가장 많이 깨지는 영역부터 시작하십시오. 가장 많이 변하는 영역으로 시작하십시오. 그런 다음 잘못된 디자인을 식별 한 후 하나씩 교체하십시오.

당신은 거의 하나의 거대한 리팩터링을 수행하는 것이 아니라 매주 작은 리 팩터의 일정한 흐름을 유지합니다. 하나의 큰 리 팩터는 일을 망칠 위험이 있으며 테스트하기가 어렵습니다.


10
특성화 테스트 추가에 +1 테스트되지 않은 레거시 코드를 수정할 때 회귀를 최소화하는 유일한 방법입니다. 변경을 시작한 후에 테스트가 실패하면 스펙에 따라 이전 동작이 실제로 올바른지 또는 변경된 새로운 동작이 올바른지 확인할 수 있습니다.
Leo

2
권리. 또는 사용 가능한 사양 검사가없는 경우 소프트웨어에 대해 지불하거나 관심이있는 사람들이 이전 동작을 실제로 원하는지 확인하십시오.
bdsl

"레거시 코드로 효과적으로 작업하기"의 사본이 있습니까? 그 책을 읽는 데 몇 주가 걸립니까? 그리고 언제 : 직장에서 근무 시간 동안, 모두가 잠들 때 밤에?
Billal Begueradj

23

GK Chesterton의 울타리를 기억하십시오 . 도로가 왜 지어 진지 이해하기 전에는 장애물을 제거하지 마십시오.

코드의 작성자와 해당 주석을 찾아서이를 참조하여 이해할 수 있습니다. 커밋 메시지, 전자 메일 스레드 또는 문서 (있는 경우)를 볼 수 있습니다. 그런 다음 표시된 조각을 리팩터링하거나 주석에 지식을 기록하여 다음 코드를 관리 할 사람이보다 현명한 결정을 내릴 수 있도록합니다.

코드의 기능과 그 당시 경고로 표시된 이유 및 경고를 무시하면 어떻게되는지 이해하는 것이 목표입니다.

그 전에는 "만지지 마십시오"라고 표시된 코드를 건드리지 않았습니다.


4
OP는 "아니요, 저자와 연락 할 수 없습니다"라고 말합니다.
FrustratedWithFormsDesigner

5
저자와 연락 할 수 없거나 문서가 없습니다.
kukis

21
@kukis : 저자, 도메인 전문가에게 연락 할 수없고 해당 코드와 관련된 이메일 / 위키 / 문서 / 테스트 사례를 찾을 수 없습니까? 그렇다면 간단한 리팩토링 작업이 아니라 소프트웨어 고고학에 대한 본격적인 연구 프로젝트입니다.
9000

12
코드가 오래되어 저자가 떠난 것은 드문 일이 아닙니다. 그들이 경쟁자를 위해 일하게되면 토론하면 누군가의 NDA를 위반 할 수 있습니다. 몇몇 경우에 저자는 영구적으로 이용할 수 없습니다. Phil Katz에게 몇 년 전에 사망했기 때문에 PKzip에 대해 물어볼 수는 없습니다.
pjc50

2
"작성자 찾기"를 "코드로 해결 된 문제 이해"로 바꾸면 이것이 최선의 대답입니다. 때때로 이러한 코드는 발견하고 추적하고 처리하는 데 몇 주 또는 몇 달의 작업이 소요되는 버그에 대한 가장 끔찍한 해결책이며, 보통 일반적인 종류의 단위 테스트로는 찾을 수없는 버그입니다. (때로는 그들이하는 일을 모르는 프로그래머의 결과이기도하지만, 첫 번째 과제는 그것이 무엇인지 이해하는 것입니다)
grahamparks

6

당신이 보여준 것과 같은 주석이있는 코드는 리팩토링 것들의 목록에서 최상위가 될 것 입니다. 요점은 코드가 심하게 악취가 나고 주석을 통해 냄새를 맡기도한다는 것입니다. 이 코드에 새로운 기능을 추가하려고 시도하는 것은 의미가 없습니다. 그러한 코드는 변경 되 자마자 죽어야합니다.

또한 주석은 최소한 도움이되지 않는다는 점에 유의하십시오. 경고 만주고 이유는 없습니다. 예, 상어 탱크 주변의 경고 신호입니다. 그러나 근처에서 무언가를하고 싶다면 상어와 함께 수영을 시도하는 것이 거의 없습니다. 임호, 그 상어를 먼저 제거해야합니다.

즉, 그러한 코드로 작업하기 전에 반드시 좋은 테스트 사례가 필요합니다. 테스트 사례가 있으면 변경되는 모든 작은 부분을 이해하여 실제로 동작이 변경되지 않도록하십시오. 코드의 모든 행동 특성이 아무런 영향을 미치지 않는다는 것을 증명할 수있을 때까지 모든 행동 특성을 유지하는 것이 최우선 과제입니다. 상어를 다루고 있다는 것을 기억하십시오. 매우 조심해야합니다.

따라서 시간이 초과 된 경우 : 코드가 무엇을 기다리는 지 정확하게 이해할 때까지 그대로 둔 다음 코드를 제거하기 전에 시간 초과가 발생한 이유를 수정하십시오.

또한, 상사가 당신이 착수하려는 노력과 그것이 왜 필요한지 이해해야합니다. 그리고 그들이 거절한다면,하지 마십시오. 이것에 대한 당신의 지원이 절대적으로 필요합니다.


1
코드가 실제 동작이 문서와 일치하지 않는 실리콘의 사전 프로덕션 샘플에서 올바르게 작동해야하기 때문에 때때로 코드가 혼란스러워 지기도합니다. 해결 방법의 특성에 따라 버그가있는 칩에서 코드를 실행할 필요가없는 경우 코드를 교체 하는 것이 좋습니다.하지만 새 코드에 필요한 엔지니어링 분석 수준없이 코드를 변경하는 것은 좋지 않습니다. 생각.
supercat

@supercat 내 요점 중 하나는 리팩토링이 동작을 완벽하게 보존해야한다는 것입니다. 동작을 유지하지 않으면 내 책에서 리팩토링하는 것 이상입니다 (이러한 레거시 코드를 다룰 때 매우 위험합니다).
cmaster

5

아마도 정상적으로 작동한다면 그러한 경고로 코드를 리팩터링하는 것은 좋은 생각이 아닙니다.

하지만 리팩토링 해야 한다면 ...

먼저 일부 단위 테스트 및 통합 테스트 를 작성하여 경고가 경고하는 조건을 테스트하십시오. 프로덕션과 유사한 조건 을 최대한 모방 하십시오 . 즉, 프로덕션 데이터베이스를 테스트 서버에 미러링하고 머신에서 동일한 다른 서비스 등을 실행할 수 있습니다. 그런 다음 리팩토링을 시도하십시오 (물론 격리 된 지점에서). 그런 다음 새 코드에서 테스트를 실행하여 원본과 동일한 결과를 얻을 수 있는지 확인하십시오. 당신이 할 수있는 경우에, 그때는 아마 생산에 리팩토링을 구현하기 위해 확인을 클릭합니다. 그러나 문제가 발생하면 변경 사항을 롤백 할 준비를하십시오.


5

계속해서 바꾸라고합니다. 믿거 나 말거나, 모든 코더가 천재가 아니며 이와 같은 경고가 개선의 장소가 될 수 있음을 의미합니다. 저자가 옳았다는 것을 알게되면 문서를 경고하거나 이유를 설명 할 수 있습니다.


4

특정 문제의 일부 측면이 간과되거나 잘못된 결론을 내리는 데 사용되기 때문에 내 의견을 답변으로 확장하고 있습니다.

이 시점에서 리팩토링 여부에 대한 질문은 시기상조입니다 (아마도 특정 형태의 '예'로 대답 할지라도).

여기서 중심적인 문제는 (일부 답변에서 언급 한 바와 같이) 인용 한 주석에 코드에 경쟁 조건 또는 여기에 설명 된 것과 같은 다른 동시성 / 동기화 문제가 있음을 강력하게 나타냅니다 . 여러 가지 이유로 특히 어려운 문제입니다. 첫째, 알다시피, 관련이없는 변경이 문제를 유발할 수 있습니다 (다른 버그도이 영향을 미칠 수 있지만 동시성 오류는 거의 항상 발생합니다.) 둘째, 진단하기가 매우 어렵습니다. 시간 또는 코드가 원인과 거리가 멀고,이를 진단하기 위해 수행하는 모든 조치로 인해 문제가 사라질 수 있습니다 ( Heisenbugs). 셋째, 동시성 버그는 테스트에서 찾기가 매우 어렵습니다. 부분적으로는 조합 폭발로 인한 것입니다. 순차 코드에는 충분하지 않지만 동시 실행의 가능한 인터리빙을 추가하면 순차적 문제가 비교할 때 중요하지 않은 지점까지 날려 버립니다. 또한 좋은 테스트 사례조차도 때때로 문제를 유발할 수 있습니다. Nancy Leveson은 Therac 25 의 치명적인 버그 중 하나를 계산했습니다.약 350 회 실행 중 1 회 발생했지만 버그가 무엇인지 모르거나 버그가있는 경우 효과적인 반복 테스트 횟수를 알 수 없습니다. 또한이 규모에서는 자동화 된 테스트 만 가능하며 테스트 드라이버는 미묘한 타이밍 제약 조건을 적용하여 실제로 버그를 트리거하지 않도록 할 수 있습니다 (Heisenbugs 다시).

POSIX pthread를 사용하는 코드 용 Helgrind 와 같은 일부 환경에는 동시성 테스트를위한 몇 가지 도구가 있지만 여기서는 그 세부 사항을 모릅니다. 환경에 적합한 도구가있는 경우 정적 분석으로 테스트를 보완해야합니다.

어려움을 더하기 위해 컴파일러 (및 런타임에 프로세서까지)는 종종 스레드 안전성에 대한 추론을 반 직관적으로 만드는 방식으로 코드를 자유롭게 재구성 할 수 있습니다 (아마도 가장 잘 알려진 경우는 이중 검사입니다) 일부 환경 (Java, C ++ ...)이이를 개선하도록 수정되었지만 잠금 관용구.)

이 코드에는 모든 증상을 유발하는 간단한 문제가있을 수 있지만 계획에 새로운 기능을 추가 할 수있는 시스템 문제가있을 가능성이 큽니다. 나는 당신이 당신의 손에 심각한 문제가있을 수 있으며, 아마도 당신의 제품에 대한 실질적인 위협이 될 수 있으며, 가장 먼저해야 할 일은 무엇이 일어나고 있는지 알아내는 것을 확신하기를 바랍니다. 이것이 동시성 문제를 드러내는 경우,보다 일반적인 리팩토링을 수행해야하는지에 대한 질문을하기 전에, 그리고 더 많은 기능을 추가하기 전에 먼저 문제를 해결하는 것이 좋습니다.


1
의견에서 "경쟁 상태"는 어디에 있습니까? 암시하는 곳은 어디입니까? 코드를 보지 않아도 아무런 기술적 가정을 많이하고 있습니다.
Robert Harvey

2
@RobertHarvey "모듈 A에게 무언가를 할 시간을주기 위해 시간 초과가 설정되었습니다." -경쟁 조건의 정의와 시간 초과는 다루기 힘든 방법이 아닙니다. 이 추론을 이끌어내는 유일한 사람은 아닙니다. 여기에 문제가 없다면 괜찮습니다.하지만 이러한 주석이 처리가 잘되지 않는 동기화를위한 위험 신호라는 점을 감안하면 질문자는 알아야합니다.
sdenham

3

나는 꽤 큰 코드베이스를 다루고 있으며 기존 코드를 리팩토링하는 데 몇 달이 걸렸습니다. 리팩토링 프로세스는 곧 우리 제품에 많은 새로운 기능을 추가해야하기 때문에 필요하다 ...]

리팩토링하는 동안 때때로 나는 ""만지지 마세요! "와 같은 주석이있는 클래스, 메소드 또는 코드 라인을 보게됩니다.

예, 특히 해당 부분을 리팩토링해야합니다 . 이러한 경고는 이전 저자들에 의해 "이 물건을 무단 변경하지 마십시오. 매우 복잡하고 예상치 못한 상호 작용이 많이 있습니다"라는 의미로 사용되었습니다. 귀사에서 소프트웨어를 추가로 개발하고 많은 기능을 추가 할 계획이라면, 이러한 것들을 정리하는 작업을 구체적으로 수행했습니다. 당신이하지 않는 그래서 안일 그것으로 변조, 당신이있어 신중 을 청소하는 작업 충전.

이러한 까다로운 모듈이 수행하는 작업을 찾아서 더 작은 문제 (원본 작성자가 수행 한 작업)로 나눕니다. 엉망에서 유지 보수 가능한 코드를 얻으려면 좋은 부분을 리팩토링하고 나쁜 부분을 다시 작성 해야합니다 .


2

이 질문은 "코드를 상속하는 방법"이라는 대시로 코드를 리팩터링 및 / 또는 정리하는시기 / 방법에 대한 또 다른 변형입니다. 우리는 모두 다른 경험과 팀과 문화를 가진 다른 조직에서 일하기 때문에 "필요하다고 생각하는 행동을하고 해고되지 않는 방식으로 행동하는 것"외에는 옳고 그른 대답이 없습니다. .

지원 응용 프로그램에 코드 정리 또는 리팩토링이 필요했기 때문에 비즈니스 프로세스를 우위에 두는 조직이 많이 있다고 생각하지 않습니다.

이 특정한 경우, 코드 주석은 이러한 코드 섹션을 변경해서는 안된다는 플래그를 제기합니다. 따라서 계속 진행하고 비즈니스가 옆으로 떨어지면 자신의 행동을 뒷받침하기 위해 보여줄 것이 없으며 실제로는 결정에 반하는 인공물이 있습니다.

따라서 항상 그렇듯이 신중하게 진행하고 변경하려는 모든 측면을 이해 한 후에 만 ​​변경해야하며 용량과 성능 및 타이밍에 매우주의를 기울이는 방법을 찾아야합니다. 코드의 주석.

그럼에도 불구하고 경영진은 현재하고있는 일에 내재 된 위험을 이해해야하며, 자신이하는 일이 그 위험보다 중요한 비즈니스 가치를 가지고 있으며 해당 위험을 완화하기 위해 수행 할 수있는 일을 수행했다는 데 동의해야합니다.

이제 우리 모두 자신의 TODO로 돌아가서 시간이 더 있다면 우리 자신의 코드 생성에서 우리가 아는 것들을 개선 할 수 있습니다.


1

네 그럼요. 이 코드를 작성한 사람이 코드에 만족하지 않았고 코드가 작동 할 때까지 찌른 것 같습니다. 그들은 실제 문제가 무엇인지 이해하지 못했을 수도 있고, 더 나쁘게 이해하고, 그것을 해결하기에는 너무 게으른 것일 수도 있습니다.

그러나이 문제를 해결하려면 많은 노력이 필요하며 이러한 수정 사항에는 관련 위험이 따른다는 경고입니다.

이상적으로는 문제가 무엇인지 파악하고 올바르게 해결할 수 있습니다. 예를 들면 다음과 같습니다.

모듈 A가 시간을 할애하도록 시간 초과를 설정했습니다. 이와 같은 시간이 지정되지 않으면 중단됩니다.

이는 모듈 A가 사용 준비가되었거나 처리가 완료된시기를 올바르게 표시하지 않음을 강력하게 암시합니다. 이 글을 쓴 사람은 아마도 모듈 A를 고치려고하지 않았거나 어떤 이유로 할 수 없었을 것입니다. 이것은 적절한 시퀀싱이 아니라 운에 의해 타이밍 의존성이 다루어지기 때문에 발생하는 재앙처럼 보입니다. 이걸 보았 으면 고치려고합니다.

이것을 바꾸지 마십시오. 날 믿어 라, 당신은 일을 깰 것이다.

이것은 당신에게 많은 것을 말하지 않습니다. 코드가 수행 한 작업에 따라 다릅니다. 그것은 어떤 이유로 든 실제로 코드를 깨뜨리는 명백한 최적화로 보이는 것을 의미 할 수 있습니다. 예를 들어, 루프는 다른 코드 조각이 의존하는 특정 값으로 변수를 남겨 둘 수 있습니다. 또는 변수를 다른 스레드에서 테스트 할 수 있으며 변수 업데이트 순서를 변경하면 다른 코드가 손상 될 수 있습니다.

setTimeout을 사용하는 것은 좋은 습관이 아니라는 것을 알고 있지만이 경우에는 사용해야합니다.

이것은 쉬운 것 같습니다. 현재 setTimeout하고있는 일 을보고 더 나은 방법을 찾을 수 있어야 합니다.

즉, 이러한 종류의 수정 프로그램이 리 팩터 범위를 벗어나는 경우이 코드 내에서 리팩토링하려고하면 노력의 범위가 크게 증가 할 수 있습니다.

최소한 영향을받는 코드를 자세히 살펴보고 문제가 무엇인지 더 명확하게 설명 할 수 있도록 주석을 개선 할 수 있는지 확인하십시오. 그것은 다음 사람이 당신이 직면하는 것과 같은 수수께끼에 직면하는 것을 막을 수 있습니다.


2
이전 문제가 더 이상 존재하지 않는 지점으로 조건이 변경되었을 수 있으며 경고 주석은 "여기 드래곤이 있습니다"라는 오래된 맵의 장소와 같이되었습니다. 상황에 대해 알아보고 상황이 역사에 전달 된 것을 확인하십시오.

2
실제로 일부 장치는 안정적인 준비 상태 표시를 제공하지 않고 최대 준비 시간을 지정합니다. 안정적이고 효율적인 준비 표시는 좋지만 때로는 표시가없는 것을 사용하는 경우가 있습니다.
supercat

1
@supercat 어쩌면 아닐 수도 있습니다. 우리는 여기서 의견을 말할 수 없습니다. 따라서 다른 사항이 없다면 구체적으로 의견을 개선하는 것이 좋습니다.
David Schwartz

1
@DavidSchwartz :이 의견은 확실히 더 도움이 될 수 있지만, 특히 문제가 예상되는지 확실하지 않은 경우 장치가 사양을 준수하지 못하는 모든 정확한 방법을 작성하는 데 프로그래머가 얼마나 많은 시간을 소비해야하는지 불분명합니다. 일시적이거나 영구적 인 것.
supercat

1

주석 작성자 는 코드 자체를 완전히 이해하지 못했을 것 입니다. 그들은 실제로 자신이 무엇을하고 있는지 알았으며 실제로 유용한 의견을 작성했을 것입니다 (또는 처음에는 경주 조건을 소개하지 않았습니다). " 나를 믿으십시오, 당신은 일을 깰 것입니다. " 와 같은 의견 은 저자가 완전히 이해하지 못한 예기치 않은 오류를 일으킨 무언가를 바꾸려고한다는 것을 나타냅니다.

코드는 추측과 시행 착오를 통해 실제로 어떤 일이 발생하는지 완전히 이해하지 않고 개발되었을 것입니다.

이것은 다음을 의미합니다.

  1. 코드를 변경하는 것은 위험합니다. 분명히 이해하는 데 시간이 걸리고, 훌륭한 설계 원칙을 따르지 않을 수 있으며 효과와 종속성이 모호해질 수 있습니다. 테스트가 제대로 이루어지지 않았을 가능성이 높으며, 코드의 기능을 완전히 이해하지 못하면 오류나 동작 변경이 발생하지 않도록 테스트를 작성하기가 어렵습니다. 레이싱 조건 (댓글이 암시하는 것처럼)은 특히 번거 롭습니다. 이것은 단위 테스트로 저장하지 않는 한 곳입니다.

  2. 코드를 변경 하지 않는 것은 위험 합니다. 이 코드는 모호한 버그와 레이싱 조건을 포함 할 가능성이 높습니다. 코드에서 치명적인 버그가 발견되거나 우선 순위가 높은 비즈니스 요구 사항 변경으로 인해 짧은 시간 내에이 코드를 변경해야하는 경우 심각한 문제가 발생합니다. 이제 1에 요약 된 모든 문제가 있지만 시간 압력을 받고 있습니다! 또한, 코드에서 이러한 "어두운 영역"은 코드의 다른 부분이 퍼져서 감염되는 경향이 있습니다.

더 복잡한 문제 : 단위 테스트는 저장되지 않습니다 . 일반적으로 이러한 레거시 코드 수정에 권장되는 방법은 먼저 단위 또는 통합 테스트를 추가 한 다음 격리 및 리팩터링하는 것입니다. 그러나 경주 테스트는 자동화 된 테스트로 캡처 할 수 없습니다. 유일한 해결책은 코드를 이해하고 이해하기 전까지 코드를 통해 생각한 다음 경주 조건을 피하기 위해 다시 작성하는 것입니다.

이는 작업이 일상적인 리팩토링보다 훨씬 까다 롭다는 것을 의미합니다. 실제 개발 작업으로 예약해야합니다.

정기적 인 리팩토링의 일부로 영향을받는 코드를 캡슐화 할 수 있으므로 적어도 위험한 코드는 격리됩니다.


-1

내가 묻는 질문은 누군가가 쓴 이유입니다. 처음에는 편집하지 마십시오.

나는 많은 코드를 작업했으며 그중 일부는 추악하고 당시 주어진 제약 조건 내에서 작업을 시작하는 데 많은 시간과 노력이 필요했습니다.

나는이 경우에 이런 일이 일어 났으며 의견을 쓴 사람이 누군가가 그것을 변경 한 다음 전체 운동을 반복하고 일을 끝내기 위해 그것을 되돌려 놓아야한다는 것을 알았습니다. 그 후, 전단 좌절에서 그들은 썼다 ... 편집하지 마라.

다시 말해서, 나는 내 삶과 더 좋은 일을하기 때문에이 문제를 다시 고치고 싶지 않다.

DO NOT EDIT (편집하지 마십시오)라고 말하면 지금 당장 알게 될 모든 것을 알고 있으므로 앞으로는 새로운 것을 배우지 않을 것입니다.

편집하지 않은 이유에 대해서는 최소한 의견이 있어야합니다. "터치하지 마십시오"또는 "입력하지 마십시오"라고 말합니다. 울타리를 만지지 않겠습니까? 왜 들어 가지 않습니까? "전기 울타리, 만지지 마십시오!"라고 말하는 것이 낫지 않습니까? 또는 "토지 광산! 입력하지 마십시오!". 그렇다면 왜 그런지 분명히 알 수 있지만 여전히 들어갈 수는 있지만 최소한 그 결과를 알고 있어야합니다.

또한 시스템 에이 마법 코드에 대한 테스트가 없으므로 아무도 변경 후 코드가 올바르게 작동하는지 확인할 수 없습니다. 문제 코드에 특성화 테스트를 배치하는 것은 항상 첫 번째 단계입니다. 코드 변경을 처리하기 전에 종속성을 위반하고 테스트중인 코드를 얻는 방법에 대한 팁은 Michael Feathers의 "레거시 코드 작업"을 참조하십시오.

결국 리팩토링에 제한을 두어 제품을 자연스럽고 유기적으로 발전시키는 데 어려움을 겪고 있다고 생각합니다.


2
이것은 이전의 9 가지 답변에서 제시되고 설명 된 포인트를 넘어서는 실질적인 것을 제공하지 않는 것 같습니다
gnat
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.