무자비하게 리팩토링할 것인가, 아니면 버리기 위해 구축할 것인가?

StackOverflow https://stackoverflow.com/questions/78806

  •  09-06-2019
  •  | 
  •  

문제

새로운 시스템 개념이나 새로운 기술이 사용되는 경우, 최상의 계획조차도 처음으로 올바르게 얻을 정도로 전능하지 않기 때문에 버리기 위해 시스템을 구축해야합니다.따라서 하나는 버릴 계획입니다.어쨌든 그렇게 될 것입니다.

-- 프레드 브룩스, 신화 속의 맨먼스 [강조 광산]

버릴 하나를 만들어 보세요.그것이 그들이 나에게 말한 것입니다.그러자 그들은 우리가 모두라고 말했어 기민한 이제 우리는 그래야 한다 무자비하게 리팩터링.무엇을 제공합니까?

그렇습니까? 언제나 문제에서 벗어나는 길을 리팩토링하는 것이 더 낫습니까?그렇지 않다면, 언제 그것을 고수해야 할지, 언제 포기하고 다시 시작해야 할지 결정하는 데 도움이 되는 경험 법칙을 제안할 수 있는 사람이 있습니까?

도움이 되었습니까?

해결책

테스트 기반 개발을 수행하는 경우 거의 모든 문제에서 리팩토링할 수 있습니다.나는 큰 어려움 없이 주요 디자인 결정을 변경했고, 10년 된 코드베이스를 구했습니다.

유일한 예외는 아키텍처가 처음부터 끝까지 완전히 잘못되었음을 발견한 경우입니다.예를 들어 스레드를 사용하여 앱을 작성했지만 여러 개의 비동기 상태 시스템이 필요하다는 것을 알게 된 경우입니다.그 시점에서 첫 번째 초안을 버리십시오.

다른 팁

일찍 버리고 나중에 리팩터링

작은 시스템에서는 버리는 것이 괜찮지만, 시스템의 크기가 크다면 그렇게 할 수 있는 리소스가 없습니다.

그러나 실제 프로젝트의 매우 필수적인 기능만 구현하는 소규모 파일럿 프로젝트를 만들 수도 있습니다.몇 번의 시행착오와 학습 및 폐기를 거친 후에는 탄탄한 핵심을 확보하고 실제 프로젝트에 대한 더 나은 이해를 얻게 됩니다.그런 다음 필요한 모든 기능을 추가하여 프로젝트의 크기를 늘릴 수 있습니다.하지만 일단 거기에 도달하면 핵심을 버릴 수 없습니다.리팩토링만 가능합니다.

당신이 충분히 무자비하다면 리팩토링의 최종 결과는 처음부터 다시 빌드했을 때 얻은 결과와 매우 유사할 것입니다. 그러나 프로세스 중에 작동하지 않는 시스템에 갇히지는 않을 것입니다.

The Mythical Man Month의 핵심 포인트 중 하나는 소프트웨어 개발의 어려운 부분은 어떻게 말해야 할지가 아니라 무엇을 말해야 할지 파악하는 것이라는 것입니다.

최근 제가 해석한 방식은 첫 번째 초안에서 얻는 가장 큰 가치는 테스트 형식으로 수집하고 보존한 요구 사항이라는 것입니다.실제로 시스템 요구 사항이 아닌 것을 테스트하지 않도록 주의한다면 ~할 수 있다 혼란스러운 상황에서 벗어나는 길을 리팩토링하세요.

테스트를 시작해야 하는 함정에 빠지지 않는 한, 실제 작업을 크게 잃지 않고 원하는 만큼의 코드를 버릴 수 있습니다.

여기서 나의 일반적인 조언은 기존 시스템을 잘못된 디자인에서 더 나은 디자인을 갖춘 시스템으로 리팩토링하라는 것입니다.이를 통해 시스템을 유지 관리하고 항상 배포할 수 있습니다.처음부터 시작하는 경우 배포할 수 있을 때까지 시간이 걸리거나 전혀 배포되지 않을 수 있습니다.

기존 시스템이 없는 새로운 코드를 작성하는 것에 대해 이야기하고 있다면 원하는 대로 약간의 코드를 작성한 다음 배포되지 않았으므로 해당 코드를 버리고 다시 시작하는 것이 좋은 생각인 경우가 많습니다( TDD를 사용).

리팩토링이 시간 낭비가 되는 지점이 옵니다.처음부터 다시 시작하면 됩니다.디자인을 상당히 유연하게 유지하고 아직 모든 것을 알지 못한다는 점을 인식한다면 아무것도 버릴 필요가 없습니다.물론 클래스가 중복될 수 있지만 전체 시스템을 버릴 수는 없습니다.

적절하게 리팩토링하려면 유연한 디자인이 필요합니다.디자인이 없거나 엄격한 디자인이 있다는 것은 리팩토링할 수 없거나 지속적인 리팩토링으로 인해 코드 기반의 유지 관리 가능성이 저하되기 때문에 결국 무언가를 버리게 된다는 것을 의미합니다.무결성을 유지하기 위해 긴 일련의 사소한 리팩토링을 완료할 수 있을 만큼 꼼꼼하고 훈련된 사람은 거의 없습니다.올스타 팀이 없으면 이런 저하가 일어날 것입니다!

요약:대부분의 문제에서 벗어날 수 있는 방법을 리팩터링할 수 있습니다.하지만 때로는 일부 디자인 요소를 지나 리팩토링할 수 없는 경우도 있습니다.그런 일이 발생하면 다시 시작할 시간입니다. 하지만 현재 가지고 있는 구성 요소 중 일부를 재사용할 수 있기를 바랍니다.

상황에 따라 다른 접근 방식이 필요합니다.개인적으로 나는 가능할 때마다 더 나은 디자인으로 리팩토링하는 것을 선호합니다.리팩토링은 재작성보다 버그가 적습니다.

그러나 하나를 버릴 계획이더라도 두 번째 버전이 올바른 방향으로 가고 있는지 확인하기 위해 여러 가지 승인 테스트를 작성하는 것은 여전히 ​​좋은 생각입니다.그런 다음 사용자 관점에서 기능이 변경되지 않도록 하면서 다음 버전으로 하나씩 마이그레이션할 수 있습니다.리팩토링과 비슷해 보이지만 조금 더 엉성한 것 같습니다.

Agile에 대해 이야기할 때 두 가지를 모두 수행할 수 있지만 일반적으로 다음을 수행합니다. 스파이크 (프로토타입) 특정 문제를 시도하고 이에 대해 배우고 더 나은 추정을 할 수 있습니다.실제로 애플리케이션을 코딩할 때 간단한 스파이크 및 리팩토링을 수행할 때는 버리십시오.

친절한 감사

새로운 문제나 기능을 해결하려고 할 때 프로토타입을 만들겠습니다.이후에는 배운 내용을 바탕으로 다시 작성하겠습니다.사실 리팩토링처럼 들리는데...무엇?어쩌면 똑같은 것일까요?흠...

때로는 하나를 버리는 것이 가장 좋은 방법이라고 생각하지만 상처를 입을 수 있습니다.제가 찾은 좋은 방법 중 하나는 하나를 버리되 기술을 잘 선택하는 것입니다.

예를 들어 저는 Ruby on Rails에서 대규모 코드베이스를 작성했는데 지난 2~3년 동안 RoR이 많이 발전했습니다.또한 아키텍처에서 수정해야 할 몇 가지 결정을 내렸습니다.그래서 하나를 버리고 처음부터 새 것을 만들려고 합니다.그러나 여전히 Ruby와 Rails로 작성하고 있기 때문에 이전 코드의 70-80% 정도를 사용할 수 있습니다.

이에 도움이 된 주요 요인은 Rails가 비즈니스 로직과 프레젠테이션 레이어를 분리하여 잘 구조화된 코드를 작성하도록 강제한다는 것입니다.처음에는 완벽하지는 않았지만 모든 것이 상당히 잘 분리되어 있고 DRY되었기 때문에 코드를 Rails v2.1로 이식하고 문제 영역을 다시 설계하고 일부 "문제" 기능을 다시 작성하는 것이 하나의 작업이었습니다. 상당히 통증이 없는 경험.

그래서 처음부터 훌륭한 기술을 선택함으로써 하나는 버릴 수 있었지만 여전히 작동하는 오래된 것의 70~80%는 가지고 다닐 수 있었습니다.

The Mythical Man Month의 이후 에세이에서 Brooks는 실제로 1개를 버릴 계획이라면 결국 2개를 버리는 결과를 얻게 될 것이라고 경고했습니다.

저는 개인적으로 이런 일이 실제 생활에서 일어나는 것을 보았습니다.우리는 프로젝트의 버전 1을 평범한 프로그래머에게 빠른 던지기로 할당했습니다. "우리는 나중에 버릴 계획입니다. 어쨌든 우리는 할 것입니다." 우리는 버전 2를 위해 그것을 다시 작성해야했지만 그 중 하나도 버려졌습니다.나는 버전 3을 본 적이 없습니다. 회사가 폐업했습니다.

Brooks가 "어쨌든 던질 계획은 어쨌든"라고 말할 때 "찾을 수있는 버그의 수는 'N+1'입니다."라고 말할 것입니다. 즉, 그것은 실질적인 조언보다는 머피의 법칙에 대한 ha-ha-ha 전용 진술입니다.여기서 얻을 수 있는 교훈은 프로토타입은 가치 있고, 좋은 글쓰기는 다시 쓰는 것이며, 작동하지 않는 것을 버리는 것을 두려워하지 않는다는 것입니다.

그러나 Joel Spolsky가 여러 에세이에서 말했듯이 코드를 읽는 것보다 작성하기 쉽고 유지하는 것보다 작성하는 것이 더 재미있기 때문에 버리고 다시 시작하는 옵션이 유혹적이기 때문에 판단을 내려야 합니다. , 그래서 당신의 자연스러운 성향은 실제로 최선의 방법이 아닐 때에도 항상 처음부터 다시 시작하는 것입니다.

여기서는 버전 관리 시스템이 큰 역할을 한다고 생각합니다.쉬운 분기(요즘 git, mercurial)를 사용하여 분산 버전 제어 시스템을 실행하면 유효한 작업 복사본을 유지하면서 더 쉽게 프로토타입을 만들고 리팩토링할 수 있습니다.다른 것에는 훨씬 더 많은 훈련이 필요합니다.

이 조직의 개발 관리자로서 저는 프로덕션 코드를 작성하는 것이 "허용되지 않습니다".

나는 그 규칙을 사용하여 하나 또는 다른 난제를 해결하는 빠르고 지저분한 개념 증명 코드를 작성한 다음 소스 제어에 체크인하고 "적절한" 개발자에게 "방법은 다음과 같습니다."라고 말합니다. 됐어, 이제 제대로 해."

그것은 여기서 "버릴 것"에 도달하는 것과 거의 비슷하며, 함께 두드리는 데 최대 두 시간이 걸릴 것입니다.오류 처리, 경계 확인 및 좋은 코드를 만드는 다른 모든 부분에 시간을 투자하는 것은 이런 종류의 작업에 시간 낭비일 것입니다. 그러나 이는 프로덕션 코드를 작성하는 데 돈을 받는 사람들이 자신의 시간을 낭비할 수 있음을 의미합니다. 프로덕션 코드를 작성하는 데 시간이 걸리고 코드 검토 시간에 관해서는 "단지 프로토타입일 뿐"이라는 변명을 하지 마십시오.

버리기 위해 하나 만든다는 것은 일을 제대로 하지 못한다는 핑계로 너무 자주 사용된다.이는 누군가의 시간을 잘 활용할 수 있을 만큼 충분히 학습하는 과정에서 실제로 충분한 문제가 발생하지 않는다는 것을 의미합니다.그리고 제대로 하다가 그냥 버리는 것은 더욱 아깝습니다.

여러 사람들이 이전에 말했듯이 모든 소프트웨어에서 가장 중요한 기능은 제공된다는 것입니다.이를 염두에 두고 나는 언제든지 "사람들이 나에게 비용을 지불하도록 하는 것"을 구축할 것이며, 리팩토링 측면에서 나의 무자비함은 작동하고 합리적으로 유지 관리할 수 있는 제품을 얻는 데 필요한 만큼만 허용하는 것입니다.

브랜치 개념을 지원하는 모든 구성 관리 시스템에서는 버릴 것을 쉽게 구축할 수 있습니다.현장에 있고 급여의 원천이 되는 기존 시스템에 획기적인 설계 변경을 도입하는 경우당신은 더 나은 지점을 가지고 있습니다.원기;그리고 효과가 없으면 버리세요.

대규모 레거시 캐시 카우 시스템을 리팩토링하면 흔히 구식 해킹으로 이어집니다.리팩토링은 해킹보다 훨씬 나은 것 같습니다.

라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top