[리팩터링] 9장 코드 삭제의 미학

공효은·2023년 5월 21일
0

refactoring

목록 보기
9/12
post-thumbnail
post-custom-banner

이번 장에서 다룰 내용

  • 코드가 개발 속도를 어떻게 늦추는지 이해하기
  • 우발적인 낭비를 방지하기 위한 한계 설정하기
  • 스트랭글러 무화과 패턴으로 전환 처리하기
  • 스파이크 및 스태빌라이즈 패턴으로 낭비 최소화 하기
  • 도움이 되지 않는 모든 것을 제거하기

9.1 다음 시대는 코드를 지우는 시대일 것이다.

오늘날 우리는 코드를 작성하고 시스템을 구축하는 데 매우 능숙하다. 우리가 구축할 수 있는 시스템은 너무 크고 복잡해서 아무도 완전히 이해할 수 없다. 이 경우 제거할 수 있는 코드를 파악하려면 시간을 투자해야하기 때문에 제거가 쉽지 않다. 이것은 우리가 다음에 해결해야할 큰 과제이다.

9.2 복잡성을 제거하기 위한 코드 삭제

9.2.1 경험 부족으로 인한 기술적 무지

기술적 무지는 무의식적으로 코드에서 잘못된 결정을 내림으로써 좋지 않은 아키텍처를 만든다. 이 문제의 유일하게 지속 가능한 해결책은 애자일 소프트웨어를 개발한 선언문에 나와있는 원칙 중 하나에서 찾을 수 있다.

"기술적 우수성과 우수한 설계에 지속적으로 주의를 기울이면 민첩성이 향상된다."

우리는 모두 책과 블로그 게시물을 읽고 콘퍼런스와 튜토리얼을 보고 공동 프로그래밍을 통해 지식을 공유하고, 가장 중요하게는 의도적인 연습을 통해 기술을 향상시키기 위해 지속적으로 노력해야한다. 연습을 대신할 수 있는 것이란 없다.

9.2.2 시간 압박으로 인한 기술적 낭비

이는 코드에서 잘못된 결정을 내림으로써 아키텍처가 좋지 않은 결과를 초래한다.
일반적인 기술 낭비는 시간 압박에서 비롯된다. 문제나 모델을 충분히 이해하지 못하기 떄문에 테스트나 리팩터링을 건너뛰기도 하고, 기한을 맞추기 위해 프로세스를 우회하기도 한다.
이런 나쁜 결정은 의도적인 것이다. 모든 경우 개발자는 외부 압력으로 인해 더 나은 지식을 거스르는 방향을 선택한다.

해결책은 개발자에게 모범 사례를 건너뛸 기회가 전혀 없게 하는 것이다. 프로젝트 관리자. 고객 및 기타 이해관계자에게 올바른 소프트웨어 구축이 필수임을 가르쳐야한다. 개발자에게는 관행이 있으며 압박을 받더라도 이를 고수해야한다.

9.2.3 환경에 따른 기술적 부채

기술 부채는 일시적으로 차선의 해결책을 선택해서 이익을 얻는것이다. 이 역시 의도적인 의사결정이지만 중요한 것은 일시적이라는 것이다.
예를 들어 적절한 아케텍처에 대한 고려 없이 핫픽스를 구현하고 중요한 문제를 해결하기 위해 적용한 다음 나중에 적절한 수정을 구현하기 위해 다시 해야 할 때 이런일이 자주 발생한다.
기술 부채를 발생시키는 것은 전략적인 결정이며, 만료일이 있는 한 본질적으로 잘못된 것이 없다.

9.2.4 성장에 따른 기술적 장애물

기술적 장애물은 개발을 더디게 만드는 모든것이다. 여기에는 문서, 테스트 및 실존하는 모든 코드는 물론 다른 모든 범주가 포함된다.

"거기 두어도 아무런 방해가 되지 않는다" 라는 말은 모두 거짓이다. 해결책은 더 이상 삭제할 것이 없을 때까지 가능한 많은 것을 삭제하는 것이다. 조금이라도 사용되지 않는 것은 사라져야한다. 사용하지 않거나 불필요한 기능, 코드,문서,위키 페이지,테스트,환경설정 플래그, 인터페이스, 버전 관리 시스템의 브랜치 등을 모두 삭제하라.

사용하지 않으면 기능은 퇴화한다.

9.3 친밀도에 따른 코드 분류

우리는 최근에 개발한 코드에 가장 익숙하다. 자주 사용하는 라이브러리와 유틸리티에도 익숙하다. 그 외의 모든 것은 알 수 없어서 다시 배워야 하기 때문에 유지보수 비용이 많이 든다.

우리가 친밀하게 알고 있는 코드를 삭제하는 것이 이해를 먼저 해야 하는 코드를 삭제하는 것보다 저렴하고 안전하다.

댄 노스는 약 6주가 지나면 코드가 알 수 없는 범주로 빠르게 이동하면서 해당 코드와의 친밀도가 떨어지기 시작한다고 주장한다.

코드의 작성자는 자연스럽게 코드를 이해하는 데 유리하다. 근데 유효기간은 6주다..

9.4 레거시 시스템에서의 코드 삭제

레거시 코드의 일반적인 정의는 '수정하기가 겁나는 코드' 이다.
서커스 팩터: 프로젝트를 진행하는 팀원 중 얼마나 많은 사람이 갑작스럽게 빠져야 프로젝트가 중단되거나 심각한 상황에 놓이는지 가리키는 지표

서커스 팩터의 지표를 높게 유지해서 위험을 최소화 해야한다.
서커스팩터를 잃는 순간 우리는 건드리기가 꺼려지는 미지의 코드, 즉 레거시 코드를 가지게 된다.
우리는 생산성을 위해 코드에 익숙해질 필요가 있으며 코드에 대한 책임을 질 필요가 있다.

9.4.1 스트랭글러 무화과 나무 패턴

해결책의 첫 번째는 레거시 코드가 얼마나 사용되고 있는지 확인하는 것이다. 거의 사용되지 않는 경우 추가 조사 없이 제거할 수 있다.

레거시 코드에 대한 통찰력을 얻으려면 각 부분이 얼마나 호출되는지 알아야한다. 그러나 그것만으로는 충분하지 않다. 이러한 호출 중에서 얼마나 많은 호출이 성공했는지도 알아야한다. (일부 코드는 호출되지만 실패하기 떄문에 그 결과가 사용되지 않는다.)

레거시 코드가 나머지 소프트웨어와 얼마나 밀접하게 연결되어 있는지 알아야한다.

마틴 파울러의 스트랭글러 무화과 나무 패턴
이 패턴은 기존 나무 줄기에 씨를 뿌리고 자라면서 숙주를 감싸 궁극적으로 숙주 나무를 교살해 죽이는 스트랭글러 무화과 나무의 이름을 따서 명명되었다.
숙주 => 레거시 시스템

//레거시 코드
class LegacyA {
  static a() {...}
}
class LegacyB {
  b() {...}
}

LagacyA.a()'
let b = new LegacyB();
b.b();
  

코드 조각이 얼마나 밀접하기 결합되어 있는지 알아보기 위해 코드를 분리해서 모든 접근이 가상의 게이트를 통과하게 할 수 있다.
새로운 패키지 및 네임스페이스에 클래스를 캡슐화한 다음 새로운 패키지에 새로운 게이트 클래스를 만든다.
새로운 패키지의 접근제어자 public을 package-private으로 줄여거면서 발생하는 오류를 게이트에 공개 함수를 추가해 수정한다.

//변경 전
class LegacyA {
  static a() {...}
}
class LegacyB {
  b() {...}
}

LagacyA.a()
let b = new LegacyB();
b.b();
  
  
// 변경 후
namespace Legacy {
  class LegacyA {
    static a() {...}
  }
  class LegacyB {
    b() {...}
  }
  export class Gate {
    a() {return LegacyA.a();}
    bClass() {return new LegacyB();}
  }
}
let gate = new Legacy.Gate();
gate.a();
let b = gate.bClass();
b.b();

이 시점에서 레거시 코드가 모두 Gate 클래스의 함수이기 때문에 얼마나 많은 접점이 있는지 알 수 있다. 또 게이트 클래스에 모니터링을 추가해서 모니터링을 쉽게 할 수도 있다. 이때 모든 호출과 성공 여부를 기록한다. 이것은 최소한의 뼈대이기 때문에 원하는 만큼 정교하게 만들 수 있다.

// 변경 전
namespace Legacy {
 //...
  export class Gate {
    a() {return LegacyA.a();}
    bClass() {return new LegacyB();}
  }
}

// 모니터링 추가 후
namespace Legacy {
  // ... 
  export class Gate {
    a() {
      try {
        let result = LegacyA.a();
        Logger.log("a success");
        return result;
      } catch (e) {
        Logger.log("a fail");
        throw e;
      }
    }
    bClass(){
      try{
        let result = new LegacyB();
        Logger.log("bClass success");
        return result;
      }catch (e) {
        Logger.log("bClass fail");
        throw e;
      }
    }
  }
}

이 코드를 운영중인 코드에 넣고 기다린다. 레거시 코드의 사용 패턴이 만들어지면 각 부분의 사용량과 호출이 항상 실패하는지 아닌지를 알 수 있다.

9.4.2 코드 개선을 위한 스트랭글러 무화과 나무 패턴 사용

어떤 항목이 호출되는 빈도는 일반적으로 그것이 얼마나 중요한지를 나타내는 좋은 지표이다.
가장 많이 호출되는 부분은 거의 확실히 마이그레이션되어야하고, 가장 적게 호출되는 부분은 높은 확률로 삭제될 수 있으므로 이런 잔가지들을 먼저 처리하고 어려운 결정을 한다.

일부 레거시 코드가 중요하거나 전략적인 경우 먼저 호출되는 빈도가 이 사실을 반영하는지 확인해야한다. UI를 개선하거나 교육 또는 마케팅을 통해 기능에 대한 호출 빈도를 늘릴 수 있다.

레거시 코드의 해당 부분을 리팩터링해서 결합과 취약성을 제거하고 코드를 최신으로 분류한다.
또는 해당 부분을 다시 만들고 다시 만들어진 코드가 준비되면 게이트를 변경해서 새 버전으로 전환할 수 있다.

일부레거시 코드가 중요하지 않고 전략적이지 않은 경우에 게이트에서 메서드를 삭제한다.

레거시 코드 => 어떻게 동작하는가 => 얼마나 사용하고 있는가 => 취약한가 => 통찰력을 얻기 위해 스트랭글러 무화과 나무 패턴을 적용. 많이 사용되는 부분을 점진적으로 마이그레이션, 사용되지 않는 부분을 삭제

9.5 동결된 프로젝트에서 코드 삭제

우리는 작업을 시작하고 시간이 지나 작업을 마칠 때 쯤 필요한 접근 권한을 얻고 사용자를 교육해야하는 장벽이 있다. 기다리는 데 시간을 낭비하는 대신 다음 작업으로 이동한다. 이렇게 우리는 동결된 프로젝트를 가지게 된다.

동결된 프로젝트는 코드에 국한되지 않는다. 여기에는 데이터베이스 테이블, 통합, 서비스 등 코드 밖의 많은 항목이 포함될 수 있다.
원래 작성자가 프로젝트에 대해 잊어버리면 프로젝트가 존재하는지 조차 알아채기가 불가능할 수 있다.
코드에는 사용하지 않는다는 표시가 없어서 변경할 때마다 고려하고 유지해야한다. 이는 정신적인 오버헤드를 가중시킨다.

동결된 프로젝트의 또다른 문제는 장벽이 제거되어도 기능이 여전히 관련성이 있다는 보장이 없다.

9.5.1 바람직한 결과를 기본값으로 설정

프로젝트가 코드 베이스 외부에 영향을 미치지 않으면 메인 브랜치에서 코드를 되돌리고 별도의 브랜치에 넣을 수 있다. 그런 다음, 태그를 지정하고 6주 후에 태그를 삭제한다고 메모를 작성해야한다. 이것은 6주안에 프로젝트를 사용하지 않으면 제거될 것이라는걸 의미한다.

프로젝트에 코드 외적인 변경 사항이 포함되어 있으면 브랜치에 넣지 못할 수도 있다. 대신 제거할 모든 구성 요소를 프로젝트 관리 도구에 기록해두고 티켓을 6주 후로 예약한다. 이런 일이 자주 발생하면 가장 자주 사용되는 구성요소의 유형을 설정하고 해제하는 스크립트를 만드는 것이 좋다.

두 경우 모든 사람이 조치를 취하지 않으면 코드가 사라진다. 이런 시나리오에서는 실수로 기술적 장애물을 추가할 수 없고 사람의 판단에 의해서만 추가된다.

9.5.2 스파이크와 스태빌라이즈(안정화)로 낭비 줄이기

스파이크와 스태빌라이즈 패턴에서는 프로젝트를 스파이크로 취급한다. 즉, 가능한 프로젝트를 일반 어플리케이션과 별도로 구현하고 고품질에 노력을 기울이지 않는다.(테스트와 리팩터링이 없음) 그러나 모니터링이 포함되어 코드가 얼마나 사용되는지 알 수 있다.

6주후 코드로 돌아가 얼마나 사용되었는지 확인한다. 많이 사용되었다면 고품질로 재구현하고 그렇지 않다면 삭제한다.
코드를 제거하는 시간도 절약되지만, 코드가 사용되는지 여부를 알지 못한 채 코드를 리팩터링하거나 테스트 하는 데 소비되는 시간도 절약할 수 있다.

아직 동작하는가? => 여전히 사용되고 있는가? => 문서화 되어 있는가? => 전략
롤백이 가능하도록 스크립트를 변경. 시간 낭비를 막기 위해 스파이크 및 스태빌라이즈를 수행

9.6 버전 관리에서 브랜치 삭제

브랜치를 만드는 주요 목적

  • 긴급 패치(hotfix)를 수행하기 위해
  • 커밋에 태그를 지정하면 release 처럼 해당 위치로 돌아갈 수 있다.
  • 다른 사람의 업무를 방해하지 않고 일하기 위해

첫 번째 및 세번째는 메인에 병합되면 삭제해야한다. 두 번째 이유는 대신 Git의 기본 제공 방법을 사용해야한다.

브랜치가 왜 쌓일까?

  • 풀리퀘스트를 병합할 때 브랜치 삭제 옵션을 선택하는 것을 잊거나 실험이 끝난 후 실험용 브랜치를 제거하는 것을 잊었을 때와 같이 단순한 실수 때문이다.
    언젠가는 코드가 필요할 수 있다고 생각해서 동결된 프로젝트, 스파이크 또는 프로토 타입을 놔두는 경우도 있다.
  • 불필요한 브랜치 제거합시다.

9.6.1 브랜치 제한으로 낭비 최소화

개발을 효과적으로 관리하고 수행할 수 있는 협업방법인 칸반을 적용할 수 있따. 칸반은 진행 중인 작업 제한 개념을 사용한다. 즉, 팀이 진행할 수 있는 티켓 수에 대한 상한선이 정해져 있다. 사람들이 새로운 작업을 시작하지 못하기 때문에 개발에서의 병목현상을 노출하는데 도움이 된다.

브랜치 수에 대한 엄격한 제한을 도입한다.
모든 사람이 동시에 작업할 수 있는 제한은 최소한 워크스테이션 수와 같아야한다.
하나의 앙상블, 페어프로그래밍을 사용하는 경우 한쌍, 그렇지 않은 경우 한 명의 개발자와 같이 독립적으로 작업할 수 있는 단위이다.

제한을 높게 설정하면 버퍼를 구축하는 효과가 있어서 시스템에 지연이 발생하지만, 일부 작업의 크기가 서로 크게 다른 경향이 있을 경우 유용하다.

버전 관리 브랜치 => 브랜치로 되돌려야하는가? => 삭제하는 것을 잊었는가? => 차단되었는가? => 정적 브랜치 대신 태그를 사용한다. 강제 정리를 위해 브랜치를 제한한다.

9.7 코드 문서 삭제

코드 문서는 위키 페이지, JavaDoc, 설계 문서, 튜토리얼 등 다양한 형태로 제공된다. 지난 장에서 메서드 내 주석을 다루었으므로 여기서는 고려하지 않는다.

문서는 정확히 세가지 조건을 충족해야한다.

  • 관련성: 올바른 질문에 답해야한다.
    ㄴ 작성 시간 낭비뿐 아니라 답을 찾을 떄마다 관련 없는 부분을 살펴봐야하고 다른 문서를 뒤져야한다.

  • 정확성: 답은 정확해야한다.
    ㄴ 최악의 경우이다. 혼란과 의심을 유발한다. 오류를 유도한다.

  • 발견 가능성: 답을 찾을 수 있어야한다.
    ㄴ 위반 시 연구 시간과 작성 시간만 낭비됨

이러한 속성중 하나라도 누락되면 문서의 가치가 떨어진다.
좋은 문서를 작성하는 것은 어렵고 관련성과 정확성을 유지하기 위한 노력이 필요하다.

9.7.1 지식을 문서화하는 방법을 결정하는 알고리즘

문서화 하는 것이 의미가 있는지 여부를 결정해야 할 때 다음 절차를 수행한다

  1. 문서화 대상이 자주 바뀌면 문서화해서 얻을 수 있는 것이 없다.
  2. 드물게 사용하는 경우 문서화한다.
  3. 그렇지 않고, 자동화할 수 있으면 자동화한다.
  4. 그렇지 않으면 외우라!

해결책은 문서 사용을 늘리는 것이므로 최신화를 자주 하도록 만드는 것이다. 이는 새로운 팀원들이 문서를 살펴보고 부정확한 사항을 수정하도록 해서 수정할 수 있다.
의심스러울때는 차이가 나는 부분에 플래그를 지정하면 된다.

문서의 정확성을 유지하는 것에 대한 또 다른 접근 방식은 테스트 케이스를 문서로 사용하는 것이다.

문서 > 최신으로 유지 되는가? > 필요한 곳이 있는가 > 정확한가 > 전략
자주 바뀌면 문서화하지 않는ㄷ. 드물게 사용하면 문서화 한다. 자동화 할 수 있으면 자동화한다. 외울 수 있으면 외운다.

9.8 테스트 코드 삭제

9.8.1 낙관적 테스트 삭제

실패한 적이 없는 테스트를 절대 신뢰하지말라. 실패한 테스트는 코드에서 오류를 발견할 때 유용하다. 문제를 바로 잡기 전에 테스트를 만들면 테스트를 통해 요건을 만족하는지 여부를 알 수 있지만, 바로잡은 후에 테스트를 만들면 항상 통과하는 것만 볼 뿐이다.

9.8.2 비관적 테스트 삭제

항상 레드인 테스트를 한다면 테스트에서 오류가 발견되더라도 경보 피로를 느껴 중대한 오류를 놓칠 위험이 있다.

9.8.3 불안정 테스트 수정

항상 같은 결과를 내지 않는 예측할 수 없는 레드 또는 그린 테스트가 있다. 이를 불안정 테스트 라고 한다.
우리는 테스트가 레드인 경우에만 행동한다. 즉, 우리 코드에서 레드 테스트를 통과하지 않은 코드는 존재할 수 없다.

9.8.4 복잡한 테스트를 제거하기 위한 코드 리팩터링

모든 리팩터링 노력은 테스트가 아니라 코드에 집중돼야한다.
테스트코드를 복잡하게 짜지맙시다.

9.8.5 속도를 높이는 테스트 문화

어떤 테스트들이 다른 테스트를 덜 자주 실행하게 만든다면 개발에 지장을 주마로 이 상황을 해결해야한다.
1. 느린테스트와 빠른 테스트를 분리하고 가능한 자주빠른 테스트를 지속적으로 실행한다.
2. 느린 테스트의 실패 원인을 관찰하고 관련 없는 경우 제거한다.
시스템 깊숙한 곳에서 주로 잘못되는 경향을 가진것들이 그 원인일 것이다. 이 경우 그 위치에 대한 테스트를 따로할 수 있다. 그 위치에 대한 테스트는 더 빠르고 구체적이여서 오류를 빨리 수정할 수 있다.

자동화된 테스트를 처리하는 방법
자동화된 테스트 > 낙관적이거나 불안정한가 > 너무 복잡한가 > 너무 느린가 > 신뢰를 주지 않는 테스트는 삭제한다. 복잡성을 줄이기 위해 코드를 리팩터링한다. 테스트 전문화로 속도를 높인다.

9.9 설정 코드 삭제

9.9.1 설정의 예상 수명으로 범위 지정

설정으로 인한 복잡성 증가를 처리하는 해결책은 가능한 한 많은 설정을 임시적인 것으로 생각하는 것 입니다. 이를 위해 예상 수명을 기준으로 설정을 실험적인 것, 과도기적인 것, 영구적인 것으로 분류한다.

실험을 위한 설정

또 다른 유형의 실험적인 설정은 변경 사항이 우수한지 여부를 테스트 하는 데 사용된다. 이를 베타 테스트 혹은 A/B 테스트 라고한다.
설정을 통해 일부 사용자는 변경 사항을 경험할 수 있지만 다른 사용자는 그렇지 않다.
이런 방식으로 변경사항이 원하는 효과를 얻을 수 있는지를 측정할 수 있다.
이 기술을 사용하면 모든 사용자에게 영향을 주지 않고 피드백을 적용하거나 변경 사항을 선택적으로 해제 할 수 있다.

실험을 위한 설정이 실험 단계를 넘어서 영구적 설정이 되어 사용자 환경을 플래그가 꺼진 것과 플래그가 켜진 것으로 분리하여 사용성이 아닌 복잡성만 증가시키는 경향이 있다. 이것은 좋지 않으므로 사전에 예방해야한다. 무엇이 실험을 위한 설정인지를 처음부터 결정하고 테스트가 완료되 즉시 제거하라는 알람을(6주 이내로 유지) 생성해야한다.

과도기적인 설정

과도기적 설정은 비즈니스 또는 코드베이스가 중요 변경 사항을 겪고 있는 동안 유용하다. 예를 들어, 레거시 시스템에서 새로운 시스템으로 전환하는 것을 들 수 있다.

이러한 대규모 변경이 6주 이내에 끝날 것이라고 예상하거나 강제할 수 없기 때문에 장기적으로 복잡성이 증가하고 높은 비용을 치러야한다. 그러나 긴 전환에는 일반적으로 활용할 수 있는 두 가지 특성이 있다.

첫째, 많은 유형의 전환이 사용자에게는 잘 보이지 않는다. 따라서 릴리스와 배포를 연결하는 것으로 만족할 수 있다. 즉, 설정을 코드 외부가 아닌 코드 내부에 코드의 일부로 포함시킬 수 있다.
코드에 포함한다는 것은 나머지와 분리된 중앙의 어떤 지점에서 전환과 관련된 모든 설정을 모을 수 있다는 것을 의미한다.
이는 다른 설정 플래그들보다 코드에 더 밀접하게 관련되어 있으면서 컬렉션으로 간주해야하는 불변속성임을 명확히 한다.

둘째, 일반적으로 전환이 완료되고 오래된 부분을 제거할 수 있는 위치가 있다. 이를 활용하면 코드를 다듬고 소소한 부분을 삭제하는 데 시간을 낭비하지 않고 전체 작업이 한 번에 완료 될 때까지 기다릴 수 있다. 이 접근 방식을 안전하게 만들기 위해서는 스트랭글러 무화과나무 패턴을 사용해서 레거시 구성요소에 대한 모든 접근을 차단해야한다.
이것은 훌륭한 TODO 리스트로서의 역할뿐만 아니라 코드에서 오류가 발생하지 않고 게이트를 삭제할 수 있을 때 레거시 구성요소도 삭제할 수 있음을 알 수 있다.
삭제 후 컴파일하기 또는 게이트의 메서드를 점진적으로 삭제해서 이를 달성할 수 있다.

영구적인 설정

사용량을 증가시키거나 유지보수가 간편해야 하기 때문에 특별하다.
사용량을 증가시키는 설정의 예는 코드 내 설정 플래그 뒤에 차이점을 넣어 두 명의 다른 고객에게 동일한 소프트웨어를 대부분 재사용하는 것이다.
또한 다양한 사용자 계층을 지원해서 다양한 비즈니스 규모에 맞게 설정할 수도 있다. 이 두가지 모두 잠재적으로 사용자 수를 두 배로 늘릴 수 있으므로 유지보수성을 높일만한 충분한 가치가 있다.

유지 보수가 쉬운 유형의 예는 사용자에게 밝은 모드와 어두운 모드 플래그를 제공하는 것이다. 이는 코드의 가장 바깥쪽 부분(스타일)에만 영향을 미치므로 유지보수성에는 영향을 미치지 않지만 일부 사용자 경험을 향상 시킬 수 있다.
사용량이 증가하지 않고 유지보수가 간단하지 않은 경우 가치가 없으므로 제거해야한다.

설정 > 실험적 용도인가? > 과도기적 용도 인가 > 영구적인가 > 실험적인 용도인 것은 가능한 빨리 제거한다. 스트랭글러 무화과나무 패턴으로 중앙 집중화한다. 사용량을 늘리지 않으면 삭제한다.

9.10 라이브러리 제거를 위한 코드 삭제

라이브러리의 코드를 유지보수할 필요는 없지만 업데이트해야 하기 때문에 때때로 코드를 수정해야한다. 이때 시간이 많이 걸리고 오류가 발생하기 쉽다. 또한 라이브러리를 사용하면 구성원이 작업을 위한 최소한의 지식을 보유해야 하기 때문에 팀의 제한된 인지부하를 더하게 된다.
라이브러리를 사용할 떄는 에측 가능성을 잃어버린다. 때때로 의존하는 기능이 더 이상 사용되지 않거나 제거되면서 이를 대체할 무언가를 만들어야한다. 떄로는 버그가 발견되고 소프트웨어가 작동하도록 임시적인 우회 코드를 만들거나 직접 라이브러리를 수정해야한다. 마지막으로 라이브러리의 버그가 수정되면 코드에서 문제가 발생하지 않도록 우회 코드를 제거하는 작업을 해야한다.

9.10.1 외부 라이브러리에 대한 의존도 제한

  1. 신뢰할 수 있는 공급 업체만 사용한다.
  2. 자주 업데이트한다.
  3. 사용에 대한 가시성을 높인다.
    ㄴ 각 라이브러리가 개선용도인지 중요 용도인지 분류한다.
  4. 의존도를 낮추기 위해 노력한다.

9.11 작동중인 기능에서 코드 삭제

코드 비용과 기능 이점의 균형을 조정할 때는 얼마나 오랫동안 복잡성의 증가를 받아들일지, 어떻게 예측 가능성을 평가할지, 어떻게 새로운 기능을 테스트할지, 사람들을 얼마나 잘 참여시키는지 등등 많은 요소가 작용한다.
비용/편익 관계에서 가치를 높이는 방법에는 리팩터링을 하거나 코드를 제거해서 비용을 줄이는 방법을 찾는것이 있다. 코드 삭제를 수행하면 코드 베이스의 가치가 더 높아진다.

요약

  • 기술적 무지, 기술적 낭비, 기술적 부채, 기술적 방해물은 개발이 더디고 더 어려워지는 원인이 된다. 기술적 무지는 일반적으로 경험 부족에서 비롯되며 기술적 우수성에 대한 지속적인 투자를 통해서만 해결된다.
    기술적 낭비는 시간 압박에서 오는 경우가 많지만 아무런 이득도 제공하지 않기 때문에 게으름과 같다. 기술적 부채는 환경에서 발생하며 일시적인 한 수용가능하다. 기술적 방해물은 코드베이스 증가의 부작용이다. 소프트웨어는 복잡한 세계를 모델링하기 떄문에 피할 수 없다.

  • 스트랭글러 무화과나무 패턴을 사용해서 레거시 시스템에 대한 통찰력을 얻고 코드를 삭제하거나 전환 기간 동안 설정을 중앙 집중화할 수 있다.

  • 스파이크와 스태빌라이즈 패턴을 사용하면 동결된 프로젝트에서 발생하는 낭비를 줄일 수 있다. 또한 동결된 프로젝트를 유지하는 대신 삭제를 기본으로 해서 기술적 방해물이 되는 것을 방지한다.

  • 잘못된 테스트를 삭제해서 테스트에 대한 신뢰도를 높이고 테스트 셋을 더욱 유용하게 만든다. 잘못된 테스트는 낙관적이거나 비관적, 또는 불안정할 수 있다. 또한 코드를 리팩터링해서 복잡한 테스트를 제거하고 느린 테스트를 전문화 하여 테스트를 더 빠르게 함으로써 테스트 셋을 개선할 수 있다.

  • 브랜체 제한을 적용하면 버전 관리에서 오래된 브랜치를 추적하는 데 낭비되는 인지부하를 줄일 수 있다.

  • 설정에 대한 엄격한 시간 제한을 설정하고 유지함으로써 복잡성을 최소화할 수 있다.

  • 외부라이브러리에 대한 의존도를 제한함으로써 업데이트 및 감사 시산을 절약하고 예측 가능성을 높인다.

  • 코드 문서가 유용하려면 관련성과 정확성이 높고 검색이 가능해야한다. 어떻게 지식을 성문화 할 것인지를 결정하기 위해 알고리즘을 사용할 수 있다.

profile
잼나게 코딩하면서 살고 싶어요 ^O^/
post-custom-banner

0개의 댓글