스프린트 하나보다 오래 걸리는 리팩토링을 어떻게 처리합니까?


49

500K 줄 이상의 코드베이스로 작업합니다. 리팩토링이 심각하게 필요합니다. 일반적인 2 주 스프린트보다 오래 걸리는 리팩토링 노력이 확인되었습니다. 이 사이트의 다른 답변에서 제안한 것처럼 작은 작업으로 나눌 수 없습니다. 반복 종료시 제품이 작동해야하며 부분 리팩토링은 항목 간의 종속성이 끔찍하므로 시스템을 사용할 수없는 상태로 둡니다. 그렇다면이 장애물에 접근하는 가장 좋은 방법은 무엇입니까? 다시 말하지만, 작은 조각으로 나누는 것은 옵션이 아니며 이미 완료되었습니다.

업데이트 : 사람들은 왜 이것이 2 주 스프린트에 적합하지 않은지에 대한 설명이 필요한 것 같습니다. 코드를 작성하는 것보다 스프린트에 더 관여합니다. 테스트 없이는 코드가없는 정책이 있습니다. 해당 정책이 항상 존재하는 것은 아니며 코드베이스의 많은 부분에 해당 정책이 없습니다. 또한 일부 통합 테스트는 여전히 수동 테스트입니다. 문제는 리팩토링 자체가 너무 크다는 것이 아닙니다. 작은 변경 사항이 시스템의 많은 부분에 영향을 미치므로 해당 부분이 여전히 올바르게 작동하는지 확인해야합니다.

월별 핫픽스가 있으므로 스프린트를 해제하거나 연장 할 수 없습니다. 따라서 스프린트를지나 연장되는이 변경은 핫픽스에 추가 된 다른 작업을 중지 할 수 없습니다.

리팩토링 및 재 설계 : 개발 프로세스가 2 주 주기로이 리팩토링을 처리하기에 충분하지 않기 때문에 재 설계로 이름을 바꿀 필요는 없습니다. 앞으로 프로세스가 개선됨에 따라 2 주주기 내에 정확히 동일한 작업을 수행 할 수 있다고 생각합니다. 여기서 문제가되는 코드는 매우 오랫동안 변경되지 않았으며 매우 안정적입니다. 이제 회사의 방향이 변화에 적응하기 쉬워 짐에 따라 코드베이스의이 부분이 나머지 부분과 마찬가지로 적응하기를 원합니다. 리팩토링해야합니다. 여기에 대한 답변을 바탕으로 일반 스프린트의 시간 프레임에서이 리팩토링 작업을 수행하는 데 필요한 스캐 폴딩이 누락 된 것이 분명해졌습니다.

대답:

Corbin March가 처음 제안한 브랜치 및 병합 접근 방식을 수행하여 이러한 문제 영역과 누락 된 테스트를 식별하는 방법에 대해 자세히 알아볼 수 있습니다. 앞으로는 Buhb가 테스트에서 누락 된 영역을 식별하고 먼저 구현 한 다음 리팩토링을 제안하는 접근 방식을 취해야한다고 생각합니다. 여기에서 많은 사람들이 항상 리팩토링의 경우라고 말한 것처럼 정상적인 2 주 스프린트주기를 유지할 수 있습니다.


23
부수적으로 이것은 리팩토링이 아닌 대규모 재 설계 입니다. nitpicking으로 이것을 사용하지 않기를 바랍니다
-IMHO

9
@Charles, "리팩토링은 일반적으로 작은 단계로 수행됩니다. 각각의 작은 단계 후에는 기능이 변경되지 않은 작업 시스템이 남아 있습니다. "위에서 링크 한 페이지에서 인용했습니다.
Péter Török

2
@Charles : 시스템 작동을 유지하면서 항상 리팩토링을 증 분식으로 수행 할 수 있습니다. 리팩토링중인 클래스 / 패키지 / 모듈 상단에 큰 "리팩토링 진행 중"주석을 달고 한 번에 하나씩 부품을 수행하십시오. 객체 모델이 전환되는 동안 임시 릴리스를 잘라 내면 괜찮습니다.
Sean McMillan

7
정기적으로 작동하는 코드를 가질 수없는 큰 단계를 수행하는 경우 리팩토링이 재 설계되는 시점에 대한 정의입니다. 당신의 말을 잘못 사용하여 당신을 부르는 것에 대해 사람들에게 화 내지 마십시오. 재 설계에 대한 질문에는 아무런 문제가 없습니다. 댓글 작성자는 단지 이미 발생한 단어를 잘못 사용하여 원하는 답변을 얻지 못하고 있음을 나타내려고합니다.
jprete

5
나는 그것이 약간 벗어난 주제라는 것을 알고 있지만, 작은 단계에서 리팩토링을 불가능하게 만드는 상황에 대해 궁금해했다. 이와 관련하여 더 많은 배경을 공유하십시오.
Buhb

답변:


14

리팩토링을 지연시키는 사치가 있다면 코드베이스를 편안하게 리팩터링 한 다음 단일 스프린트로 리팩토링 할 수있는 지점에 단위 테스트 및 자동 통합 테스트를 추가하는 데 중점을 두는 것이 좋습니다.


68

나의 제안:

  1. 지점 만들기
  2. 트렁크에서 지점으로 매일 병합하고 충돌을 해결하십시오.
  3. 끝날 때까지 일하십시오. 여러 스프린트를 위해 지점이 핵심 개발 외부에있을 수 있습니다.
  4. 트렁크로 다시 병합하십시오.

아마도 추악해질 것입니다. 부럽지 않아 필자의 경험에 따르면 프로젝트를 대폭 변경하면 진행중인 개발을 새로운 패러다임으로 병합하는 것이 더 쉬우 며 새로운 패러다임을 모든 것이 끝난 후 현재 변경 된 트렁크에 병합하는 것이 더 쉽습니다. 아직도 아파요.


1
우리는이 접근법을 사용하는 것에 대해 논의했으며, 우리가 다루기 전에 다른 아이디어가 나오지 않는다면, 이것이 우리가 계획 한 것입니다.
찰스 램버트

3
철저한 리팩토링을 수행하려는 경우 트렁크와 지점 사이에 많은 오버 헤드 병합이 필요합니다.
조르지오

대부분의 경우 합병 된 변경 사항은 해당 코드에 영향을 미치지 않습니다. 신뢰할 수있는 결과를 보장한다면이 변경에 대한 타임 라인을 연장해도 상관 없습니다.
찰스 램버트

1
변동성을 고려할 때 프레젠테이션에서 제안하는 것처럼 보일 수 있습니다 .Git 은 이러한 종류의 추측 분기 및 병합을 용이하게 하므로 Git 을 고려해야 합니다.
John Tobler

1
@ Giorgio : 나도 그래, 매일 병합은 약간 편집증처럼 보이지만 실제로는 팀 규모에 달려 있습니다. 사람이 많을수록 더 많이 변경되며 더 자주 병합해야합니다. 당신이 일할 시간을 갖고 싶다면 매일은 최저 한계처럼 보입니다.
Matthieu M.

40

모든 작업을 (인공적인) 2 주 스프린트로 수행 할 수있는 것은 아니므로 상식이 요구됩니다. 더 이상 세분화 할 수없고 완료해야한다면 그냥 타십시오. 이 과정은 최종 결과보다 중요하지 않으며 절대로 깨지지 않는 법보다는 지침으로 보여야합니다.


3
당신의 대답은 주제에 대한 아주 좋은 정보입니다. 나는 당신이 말한대로 "계속해서"여기에 있습니다. 나는 기존의 프로세스와 병렬로 실행되는 프로세스를 만들거나 현재의 상황을 해결하기 위해 현재 프로세스를 수정하기 위해 정보를 얻기를 희망하여 질문했습니다. 적어도 2 번 이상 일어날 것이므로 개발자에게 작업 지침을 갖도록 할 말이 필요합니다.
찰스 램버트

+1은 "이 프로세스는 최종 결과보다 중요하지 않으며 절대로 깨지지 않는 법보다는 지침으로 보여야합니다." -사람들은 이것을 정말로 잊어 버리는 것 같습니다.
Bjarke Freund-Hansen

32

3, 4 또는 5 주 스프린트를 수행하십시오. 누가 신경 쓰나요? 짧은 시간 안에는 아무것도 할 수 없다는 것을 분명히 알고 있으므로 싸움을 그만두십시오.

Royal Society of Blind Agile Adherance에서 동료들에게 알리지 마십시오.


조직상의 이유로 (월별 핫픽스) 2 주 스프린트는 변경하기가 매우 어렵습니다.
스티브 베넷

10

Michael Feathers의 ' 레거시 코드로 효과적으로 작업하기 '책을 시작하는 것이 좋습니다 . 그는 리팩토링 스타일 변경의 범위를 줄이기 위해 다양한 기술을 다룹니다.


확실히 좋은 책이지만 여러 스프린트로 리팩토링을 나누는 것은 다루지 않습니다.
Adam Lear

4
제목에서 알 수 있듯이 레거시 코드를 효과적으로 사용하는 방법을 배우기 시작할 때 가장 좋은 책이기 때문에 +1을 줄 것입니다. 이 질문을하고 사물을 더 작은 단계로 나누는 것과 관련된 내용을 이해하지 못하는 사람과 관련이 있습니다.
찰스 램버트

@Anna-그러면 25 장을 다시 읽고 싶을 것입니다.이 장에서는 작은 변경을 막는 커플 링의 종류를 끊는 기술에 대해 설명합니다.
kdgregory

@kdgregory 박람회에 충분합니다. :) 더 멋진 답변을 위해 답변에 추가해 주시겠습니까?
Adam Lear

7

릴리스 창에서 완료 할 수없는 대규모 리팩토링 또는 재 작성 작업이있는 경우 시스템에서 그대로 기능을 그대로 둡니다. 그러나 시간이 허락 할 때마다 새로운 리팩토링 된 레고 블록 기능부터 시작합니다. 결국, 레고 블록이 충분한 상태가되어 스프린트는 레고 블록을 응용 프로그램에 연결하고 사용자를 위해 켤 수있는 충분한 시간을 제공합니다.

더 간결하게, 우리는 새로운 이름을 사용하여 큰 기능을 분리하거나 재 작업합니다. 그런 다음 마지막으로 불쾌한 이전 코드 대신 이름이 바뀐 리팩토링 된 작업을 사용합니다.


이것은 좋은 생각이지만,이를 위해서는 높은 수준의 커뮤니케이션이 필요합니다. 예를 들어, 코딩 할 때 어느 곳에서도 사용되지 않고 공개되지 않은 메소드를 식별하면 제거합니다.
찰스 램버트

5

코드가 제대로 작동하는 방법을 알아 내기 위해 한 번의 스프린트를 사용하십시오. 이것은 사용되지 않는 메소드 및 클래스, 랩퍼, 어댑터 등의 형태를 취할 수 있습니다. 리팩토링을하면 코드가 더 깨끗해지기 위해 짧은 시간 동안 코드가 더러워 질 수 있습니다. 괜찮아. 지금은 할 수 없다고 말하고 있습니다. 나는 그것이 옳지 않다고 생각합니다. 프로세스가 완료 수 있다면 어떻게 될지, 프로세스 를 만들기 위해 어떤 조치를 취할 수 있는지 생각하십시오. 그런 다음 들어갑니다.


우리는 이미이 모든 것을했습니다. 그것이 내가 무너질 수 없다는 것을 분명히 표현한 이유입니다.
찰스 램버트

정말? 스프린트 전체를 단순히 시스템을 중단하지 않고 리팩토링하는 방법을 계획하는 데 보냈는데 아무것도 없었습니까? 전담 계획 스프린트가 아무 것도 없었다고 믿기가 어렵습니다. 어쩌면 컨설턴트를 데려 와야 할 수도 있습니다 (아니, 나는 하나가 아니며 공연을하려고하지 않습니다).
Carl Manaster

1
나는 아무 말도하지 않았다. 나는 우리가 당신이 묘사 한 것과 비슷한 과정을 겪었고 다른 한 쪽 끝에서 단거리 스프린트로 리팩토링 할 수없는 코드로 나왔다고 말하고있었습니다.
찰스 램버트

"코드가 제대로 작동하는 방법을 알아내는 데 단 한 번의 스프린트를 맡기십시오." "우리는 이미이 모든 작업을 완료했습니다." 지금 다른 말을하고 있습니까? 논쟁의 여지가있는 경우 죄송하지만 이해가되지 않습니다.
Carl Manaster

5

Corbin March의 답변에 +1했습니다. 이것이 바로 제가 생각한 것입니다. 코드베이스가 약간 추악한 것처럼 들리며 한 번의 스프린트 사이클 이상으로 정리해야합니다.
코빈이 말했듯이

  1. "리팩토링 프로젝트"로 분기
  2. 지점 변경 테스트
  3. 품질 관리 테스트를 위해 테스트 환경으로 승격
  4. 리팩토링이 완료 될 때까지 점진적으로 트렁크에 다시 병합하십시오.

나는 당신이 당신의 개발자 매니저에게 이것을 판매하는 데 아무런 문제가 없을 것이라고 확신합니다 .PM이 그것을 보는 데 어려움을 겪고 있다면 로마가 하루에 지어지지 않았다고 설명하고 로마에 던져진 모든 쓰레기를 청소하십시오. 거리는 하루도 끝나지 않을 것입니다. 리팩토링에는 다소 시간이 걸리지 만 유지 관리가 쉽고, 개선 버전이 더 빠르며, 프로덕션 티켓이 적으며, SLA가 더 충실하다는 측면에서 가치가 있습니다.


1
나는 모든 사람들에게 이야기 할 수있는 탄약을 가지고 있습니다. 발표 할 때 공식 계획이 필요합니다. 여기에 대한 답변에서 반복 가능한 솔루션을 제안 할 것입니다.
찰스 램버트

4

실제로 원하는 재 설계는 큰 작업이지만 작은 조각을 리팩터링하여 개별 종속성을 분리 / 분리 할 수 ​​있습니까? 알다시피, 의심스러운 경우 간접 지정을 추가하십시오. 이러한 각 분리는 완료 할 수없는 매머드보다 작은 작업이어야합니다.

종속성이 제거되면 스프린트 내에서 얻을 수 있도록 나머지 리팩토링 태스크를 분리 할 수 ​​있습니다.


3

현재 작업중 인 프로젝트에서 4 주 스프린트를 사용하고 있습니다. 때로는 사용자 스토리를 끝내지 못하고 다음 스프린트 중에 다시 시작합니다.

그러나 IMHO는 리팩토링을 4 주 스프린트에 맞는 작은 이야기로 나눌 수 있어야합니다. 4 주 내에 코드를 일관된 상태로 만들 수 없으면 응용 프로그램을 리팩토링하지 않고 다시 작성하는 느낌이 듭니다.


4 주 스프린트가이를 커버해야합니다. 그러나 다른 버그 수정 등으로 인해 현재 2 주 동안의 스프린트를 중단 할 수 없습니다. 따라서 이것은 2 개 이상의 스프린트를 통해 연장되어야합니다. 따라서 내 문제의 요점.
찰스 램버트

내가 말했듯이, 우리는 4 주 스프린트를 사용하고 있으며 4 주 후에 이야기가 끝나지 않으면 다음 스프린트를 위해 일정을 잡습니다. 최소 2 주 스프린트 종료시 시스템을 일관성있는 상태로 유지할 수 있습니까 (그리고 다음 스프린트 동안 계속할 수 있습니까)?
Giorgio

확인 가능한 일관된 상태가 아닙니다 .
찰스 램버트

다른 사람들이 "리팩토링"이 아닌 다른 단어를 찾기를 희망했던 노력에 내 파동을 더해야합니다. 리팩토링은 잘 정의되어 있으며 범위는 시간이 많이 걸리는 재 설계 및 재 프로그래밍보다 훨씬 즉각적이고 단기적입니다.
존 토 블러

2

특정 작업이 2 주 스프린트주기보다 오래 걸리면 다른 시간에 작업이 예정되어있는 것이 좋습니다. 팀에서 리팩토링의 필요성을 확인했으며 이것이 중요합니다. 때로는 다른 옵션이 없습니다 ... 그렇습니다.

리팩토링을 시작할 때가되면 간단히 일반 스프린트를 중단합니다. 선택의 여지가 없습니다. 분기, 리팩터링, 테스트, 병합-스마트 버전 관리를 사용하십시오. 일부 대규모 프로젝트를 리팩토링하는 것이 기능보다 우선하는 시점이 항상 있습니다. 가능하면 더 나은 유연성을 위해 우려 사항을 분리하려고 시도합니다.


우리는 그것을 영원히 연기 할 수 없으며 귀하의 답변은 리팩토링을 수행하는 방법을 다루지 않습니다.
찰스 램버트

@Charles : '또 다른 시간을 맞이 했습니다.' ;) 나는 프로젝트를 취소한다고 말하지 않았다.
IAbstract

2

최근 코드베이스의 일부 (또한 조금 더 큼)와 동일한 문제를 겪어 왔으므로 몇 가지 통찰력을 공유 할 수 있기를 바랍니다. 내 상황에서 코드베이스는 다른 팀에 의해 개발되었으므로 원래 개발자의 아무도 리팩토링에 관여하지 않았습니다. 코드베이스에 대한 나의 경험은 약 1 년이었고 다른 개발자는 2 년 동안 작업했습니다.

다른 답변에 관한 두 가지 작은 메모를 여기에 허용하십시오.

  • 분기는 스스로 놀이터를 만드는 데 도움이되지만 변경 사항을 하나의 큰 변경 세트에서 트렁크로 병합하지 마십시오. 나머지 팀원들에게는 심각한 문제가 생길 것입니다.
  • 점진적으로 수행해야하며 수행 할 수 있습니다. 변명하지. 레거시 코드 커버로 효율적으로 작업하기를 읽으십시오 . 다시 읽으십시오.
  • 당신이 그것을 할 수 있다고 생각하는 것은 큰 걸음입니다. 더 많은 작업이 필요한 것 같지만 점진적으로 처리하는 것이 훨씬 쉽습니다.

2 주 이상 동안 "예약 외"로가는 것은 눈에 띄지 않을 것입니다. 프로젝트 관리와 팀, 그리고 더 중요한 팀의 지원을 받아야합니다. 팀 이이 리팩토링에 전념하지 않으면 (그리고 먼 미래가 아닌 지금 그렇게하십시오), 문제가 생길 것입니다.

혼자하지 말고 페어 프로그래밍을 사용하십시오. 그렇다고해서 항상 같은 키보드 앞에 앉아 있어야하는 것은 아니지만 작고 좁은 작업 (예 :이 클래스의 동작을 캡처하는 쓰기 테스트)을 개별적으로 처리 할 수 ​​있습니다.

스크래치 리팩토링을 수행하고이를 그대로 처리하십시오. (일종의 "throw-away"프로토 타입 리팩토링, "throw-away"비트가 중요합니다!) 솔직히, 리팩토링이 미칠 모든 영향을 알지 못할 것입니다. 스크래치 리팩토링은 특정 측면에서 도움이됩니다.

  • 당신은 그들이 존재한다는 것을 전혀 모르는 시스템 조각들을 발견 할 것입니다.
  • 모듈이 상호 연결되는 방식에 대해 훨씬 더 잘 볼 수 있습니다
  • 시스템을 모듈로 그룹화하는 새로운 방법을 발견 할 것입니다. 현재 이해하는 것과 크게 다를 수 있습니다. 파트너와 통찰력을 토론하십시오. 새로운 견해를 증류하십시오. 현재 상황과 논리적으로 속한 위치를 나타내는 짧은 아키텍처 백서를 작성하거나 다이어그램을 그리십시오.

스크래치 리팩토링을 마쳤 으면 모든 것을 바꿀 수는 없다는 것을 알게 되길 바랍니다. 기분이 나쁘고, 뚱뚱한 혼란 일 뿐이며 스위치를 뒤집어 작동시킬 수는 없습니다. 이것은 나에게 일어난 일이며, 상황에 따라 다를 수 있습니다.

그러나 파트너와 저는 시스템에 대해 훨씬 더 잘 이해했습니다. 이제 우리는 개별적이고 작은 (아직 큰) 리팩토링 / 재 설계를 식별 할 수있었습니다. 우리는 시스템의 비전을 다이어그램으로 캡처하여 해당 비전을 구현하기 위해 우리가 생각 해낸 백 로그 항목과 함께 팀과 공유했습니다. 공통된 합의에 힘 입어 다음 반복 과정에서 구현할 항목을 결정했습니다.

마지막으로 큰 화이트 보드를 사용하는 데 도움이되었습니다. 머리 속에 보관해야 할 것이 너무 많습니다. 메모하는 것이 매우 중요합니다. 오늘이 끝났고 내일하고 싶은 일을 포착하여 하루가 끝날 때 간단한 메모를 작성하십시오. 그것은 큰 시간을 편안하게하는 데 도움이되며 작업을 계속하려면 편안한 시간이 필요합니다. 행운을 빕니다!


1

추가 개발이 수행되지 않는 유지 관리 기간을 시작하십시오. 재 설계를 수행 한 다음 개발 스프린트를 재개하십시오.


0

우리에게는 두 가지 유형의 작품이 있습니다.

  1. 근무 시간
  2. 천재 작품

많은 방법이 같은 개발자들에게 이미 알려져 있기 때문에 리팩토링은 일반적으로 작업의 첫 번째 유형으로 구성 DRY , SRP , OCP , DI 프로젝트가 리팩토링 할 두 달 걸리는 경우에 따라서 등, 단순히 두 달 소요 ,가 주위에 방법이 없습니다. 따라서 제 제안은 원래 프로젝트를 리팩터링하지 않고 현재 상황에서 작동하게하는 것입니다. 이해 관계자와 제품 소유자로부터 새로운 요청과 요구 사항을받지 마십시오 . 그런 다음 리팩토링되고 준비 될 때까지 팀이 프로젝트를 진행하도록하십시오.


0

도움이 될만한 한 가지 제안 : 2 주 스프린트 내에 코드를 리팩토링 하고 다시 테스트 할 시간이 충분하지 않은 테스트되지 않은 코드가있는 경우 먼저 코드와 관련이없는 다른 작은 변경 사항을 작성하여 집중할 수 있습니다. 첫 스프린트를위한 테스트를 작성할 때. 리팩토링하려는 코드의 테스트되지 않은 여러 클라이언트를 식별 할 수 있습니다. 한 명의 고객을 선택하고 해당 고객에 대한 테스트를 작성하도록하는 비즈니스에 대한 일부 사용을 변경하십시오. 코드에 익숙해지면서 코드 작업에 더 많은 테스트를하고 약간의 기여를하는 리팩토링을 달성 한 경우 리팩토링을 수행 할 수있는 훨씬 나은 위치에있게됩니다. ) 한 번의 반복으로 테스트합니다.

또 다른 방법은 문제가되는 코드를 복사하여 리팩터링 한 다음 한 번에 하나씩 클라이언트를 새 코드로 옮기는 것입니다. 이 작업은 여러 번 반복하여 나눌 수 있습니다.

포기하지 마십시오. 큰 리팩토링을 더 작은 단계로 나눌 수 없다는 것을 인정하지 마십시오. 가장 쉽고 빠른 방법은 반복보다 시간이 오래 걸릴 수 있습니다. 그러나 이것이 반복 크기의 청크를 수행 할 수있는 방법이 없다는 것을 의미하지는 않습니다.

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.