잘못된 추상화보다 중복을 선호하라 (2016)

1 hour ago 1
  • 잘못된 추상화보다 코드 중복이 훨씬 싸며, 성급한 공통화가 장기 유지보수 비용을 키운다고 봄
  • 처음에는 합리적이던 추출도 요구사항이 조금씩 달라지면 매개변수와 조건문이 붙어 원래 의도를 흐림
  • 공통 추상화가 여러 아이디어를 떠안기 시작하면 코드는 조건 중심 절차로 변하고, 새 기능을 넣을수록 더 깨지기 쉬워짐
  • 기존 코드에 들인 노력을 지키려는 매몰비용 오류를 경계하고, 필요하면 추상화를 호출부로 다시 인라인해 실제로 필요한 코드만 남겨야 함
  • 잘못된 추상화가 드러났다면 중복을 다시 도입해 현재 요구사항의 공통점을 새로 관찰하고, 그다음에 다시 추출하는 편이 더 빠름

잘못된 추상화가 만들어지는 흐름

  • duplication is far cheaper than the wrong abstraction”라는 문장은 RailsConf 2014 발표의 일부였지만 이후에도 계속 회자됨
  • 흔한 실패 경로는 다음과 같음
    • 개발자 A가 중복을 발견함
    • 중복을 메서드나 클래스로 추출하고 이름을 붙여 새 추상화를 만듦
    • 호출부의 반복 코드를 새 추상화 호출로 대체함
    • 시간이 지나 거의 맞지만 완전히 같지는 않은 새 요구사항이 등장함
    • 개발자 B가 기존 추상화를 유지하려고 매개변수를 추가하고, 값에 따라 다른 경로를 타는 조건문을 넣음
    • 이후 새 요구사항마다 매개변수와 조건문이 늘어나며 코드 이해가 점점 어려워짐
  • 한 번 만들어진 코드는 보존해야 할 투자처럼 보이기 쉬움
    • 이미 들인 노력을 아깝게 여기는 심리가 작동함
    • 코드가 복잡하고 이해하기 어려울수록, 그만큼 중요하고 오래 걸렸을 것처럼 느껴져 버리기 어려워짐
    • 이는 매몰비용 오류와 연결됨

중복으로 되돌아가 다시 추출하기

  • 잘못된 추상화 위에서 새 요구사항을 계속 구현하면 공유 코드는 조건문 중심으로 변하고, 기능을 추가할수록 더 불안정해짐
  • 이때 빠른 길은 더 밀어붙이는 것이 아니라 뒤로 돌아가는 것
    • 추상화된 코드를 각 호출부에 다시 인라인해 중복을 재도입함
    • 각 호출부에서 전달하던 매개변수를 기준으로 실제 실행되는 코드만 확인함
    • 해당 호출부에 필요 없는 코드를 삭제함
  • 인라인 과정은 추상화와 조건문을 함께 제거하고, 각 호출부를 자신에게 필요한 코드만 가진 상태로 줄임
  • 같은 추상화를 호출하는 것처럼 보였던 코드도 실제로는 각 호출부가 상당히 고유한 코드 경로를 실행하고 있었을 수 있음
  • 이전 추상화를 완전히 제거한 뒤에야 중복을 다시 관찰하고, 현재 요구사항에 맞는 새 추상화를 추출할 수 있음
  • 매개변수와 조건 경로가 공유 코드에 계속 추가되고 있다면 그 추상화는 더 이상 맞지 않을 가능성이 큼
    • 처음에는 맞는 추상화였을 수 있음
    • 요구사항이 바뀌면서 더 이상 같은 형태로 유지하기 어려워졌을 수 있음
  • 잘못된 추상화에서는 중복을 다시 도입하는 일이 후퇴가 아니라 더 나은 전진이 됨
Read Entire Article