호환되지 않는 변경을 한 번에 하지 않고, 새 것을 추가하고(팽창, Expand) 옛 것과 함께 쓰다가 옛 것을 걷어 내는(수축, Contract) 단계로 나눠 하는 방법. 각 단계가 배포 가능한 상태라 중간에 멈춰도 안전하다.
데이터베이스 컬럼 이름을 바꾸는 예:
- 새 컬럼을 추가한다
- 쓰기를 두 컬럼에 모두 하고, 기존 데이터를 새 컬럼으로 옮긴다
- 읽기를 새 컬럼으로 바꾼다
- 옛 컬럼을 쓰는 코드를 없앤 뒤 옛 컬럼을 지운다
- 함수 이름이나 API(Application Programming Interface) 시그니처를 바꿀 때도 같다. 새 함수를 만들고 옛 함수가 새 함수를 부르게 둔 채 호출부를 하나씩 옮긴다(함수 선언 바꾸기)
- 켄트 벡의 New Interface, Old Implementation(한국어판 "새로운 인터페이스로 기존 루틴 부르기". 새 인터페이스를 만들고 안에서 옛 구현을 부른다)도 같은 생각이다(정리(Tidying))
- 공개 API라면 옛 버전에 의존하는 사용자가 생각보다 많다는 점을 염두에 둔다(하이럼의 법칙)
- 마이그레이션 중 스키마와 코드가 어긋나는 문제는 스키마 드리프트, 커밋 단위로 나누는 요령은 커밋 메시지와 원자적 커밋 참고
- 변경 비용을 되돌릴 수 있는 작은 조각으로 쪼갠다는 점에서 가역성 이야기와 닿아 있다
출처: martinfowler.com: Parallel Change 다닐루 사투(Danilo Sato) · 『리팩터링 2판』 마틴 파울러 (원서 Refactoring, 2nd Edition) · 『켄트 벡의 Tidy First?』 켄트 벡 (원서 Tidy First?)