레트로핏 순서
개요
레거시 시스템은 대개 이상적인 구조가 아니다.
그래서 하네스를 붙일 때 가장 흔한 실패는
처음부터 모든 것을 다 막으려는 것이다.
이 문서는 현실적인 retrofit 순서를 정리한다.
먼저 하지 말아야 할 것
규칙만 잔뜩 늘리는 것
구조가 준비되지 않았는데 규칙만 늘리면, 예외와 disable이 함께 늘어난다.
가장 넓은 문제부터 해결하려는 것
“전체 아키텍처를 정리하자"는 말은 맞지만, 실행 단위로 쪼개지지 않으면 대부분 멈춘다.
테스트를 나중으로 미루는 것
테스트에서 우회가 남아 있으면, 새 경계는 빠르게 무력화된다.
권장 순서
1. 가장 위험한 direct path를 먼저 찾는다
첫 단계는 구조 전체를 이해하는 것이 아니라, 가장 반복적으로 사고를 만드는 직접 경로를 찾는 것이다.
예:
- UI의 파일 시스템 직접 접근
- provider 없는 direct state access
- planner 없는 executor 호출
- validation 생략 경로
이 단계의 목표는 문제를 줄이는 게 아니라, 첫 번째 합법 경로 후보를 정하는 것이다.
2. 합법 경로 하나를 만든다
우회를 막기 전에 정상 경로를 먼저 만들어야 한다. 정상 경로가 없으면 팀은 계속 우회한다.
좋은 합법 경로의 조건:
- 사용 방법이 명확하다
- 기존 우회보다 크게 불편하지 않다
- 계약이 선명하다
- 이후 validator와 enforcement를 붙일 수 있다
하네스 도입은 금지부터가 아니라, 합법 경로 설계부터 시작하는 편이 안정적이다.
3. 새 코드부터 경계를 따르게 만든다
기존 코드를 한 번에 다 고치려 하지 말고, 새 코드가 우회를 복제하지 못하게 만드는 편이 효과적이다.
- 신규 변경은 합법 경로만 사용
- 새로운 direct path는 바로 금지
- review 기준도 새 경계 쪽으로 맞춤
이 단계에서 미래 부채의 확산을 먼저 끊는다.
4. 정적 차단을 가능한 만큼 붙인다
새 경계가 생겼다면 그 다음은 차단이다. 가능하면 이른 단계에서 막는다.
- lint
- analyzer
- type restriction
- import boundary
- build check
정적 차단이 붙기 시작하면, 규칙이 설명에서 시스템으로 이동한다.
5. 테스트 환경을 같은 경계로 맞춘다
많은 팀이 여기서 멈춘다. 하지만 테스트가 그대로면 구조는 다시 열린다.
- fixture도 같은 진입점을 사용
- story도 같은 provider 구조를 사용
- test utility가 direct path가 되지 않게 제한
테스트는 나중 단계가 아니라, 구조를 고정하는 핵심 단계다.
6. 반복되는 우회를 rule 후보로 올린다
일단 첫 경계가 생기면, 그다음부터는 반복 우회를 rule 후보로 올리면 된다.
좋은 후보의 특징:
- 자주 반복된다
- 비용이 크다
- 경로가 비교적 분명하다
- 차단 가능성이 높다
모든 문제를 rule로 만들 필요는 없다. 반복되고 구조를 무너뜨리는 문제부터 고정하면 된다.
7. 마지막에 범위를 넓힌다
첫 성공 이후에만 범위를 넓히는 편이 좋다.
- 한 레이어에서 두 레이어로
- 한 규칙에서 여러 규칙으로
- 한 환경에서 모든 환경으로
핵심은 한 번에 완벽해지는 것이 아니라, 우회 복제를 단계적으로 끊는 것이다.
이 순서가 중요한 이유
이 순서는 단순 작업 분해가 아니다. 다음 위험을 피하기 위한 순서다.
- 합법 경로 없이 금지만 늘리는 것
- 구조 정리 없이 enforcement만 붙이는 것
- production만 막고 test를 열어두는 것
- 너무 넓은 범위를 한 번에 바꾸다 실패하는 것
즉 retrofit order는 기술 순서가 아니라, 통제 실패를 줄이는 순서다.
요약
레거시 구조에 하네스를 도입할 때는 다음 순서가 현실적이다.
- 가장 위험한 direct path를 찾는다
- 합법 경로 하나를 만든다
- 새 코드부터 그 경계를 따른다
- 정적 차단을 붙인다
- 테스트 환경을 같은 구조로 맞춘다
- 반복 우회를 rule 후보로 올린다
- 마지막에 범위를 넓힌다
레거시에 하네스를 도입하는 핵심은 모든 것을 한 번에 고치는 것이 아니라, 우회 복제가 계속 일어나는 경로부터 하나씩 닫는 것이다.