본문 바로가기

개발/클린 코드

클린 코드 8장 - 경계

  시스템에 들어가는 모든 소프트웨어를 직접 개발하는 경우는 드물다. 어떤 식으로든 이 외부 코드를 우리 코드에 깔끔하게 통합해야만 한다. 이 장에서는 소프트웨어 경계를 깔끔하게 처리하는 기법과 기교를 살펴본다. 

 

외부 코드 사용하기

  패키지 제공자나 프레임워크 제공자는 적용성을 최대한 넓히려 애쓴다. 반면, 사용자는 자신의 요구에 집중하는 인터페이스를 바란다. 이런 긴장으로 인해 시스템 경계에서 문제가 생길 소지가 많다. 

  책의 예시처럼, 프로그램에서 Map<String,Sensor> 인스턴스를 여기저기로 넘긴다면, Map 인터페이스가 변할 경우, 수정할 코드가 상당히 많아진다. 자바5가 제네릭스를 지원하면서 Map 인터페이스가 변했다는 사실을 명심해야 한다. 실제로 제네릭스 사용을 금지하는 시스템도 보았다. 기존 시스템에서 Map을 너무 많이 사용한 탓에 변경할 코드 역시 너무 많은 탓이었다.

 

아래의 코드는 경계 인터페이스인 Map을 Sensors 안으로 숨긴다. 제네릭스의 사용 여부는 Sensors 안에서 결정한다.

public class Sensors {
   private Map sensors = new HashMap();
   
   public Sensor getById(String id) {
      return (Sensor) sensors.get(id);
   }
}

또한 Sensors 클래스는 프로그램에 필요한 인터페이스만 제공한다.

 

Map과 같은 경계 인터페이스를 이용할 때는 이를 이용하는 클래스나 클래스 계열 밖으로 노출되지 않도록 주의한다. 

Map 인스턴스를 공개 API의 인수로 넘기거나 반환값으로 사용하지 않는다. 

경계 살피고 익히기

  만약 외부에서 가져온 패키지를 사용하고 싶다면 어디서 어떻게 시작해야 좋을까?

외부 패키지 테스트가 우리 책임은 아니다. 하지만 우리 자신을 위해 우리가 사용할 코드를 테스트하는 편이 바람직하다. 

곧바로 우리쪽 코드를 작성해 외부 코드를 호출하는 대신 먼저 간단한 테스트 케이스를 작성해 외부 코드를 익히면 어떨까?

이를 학습 테스트라고 부른다

 

학습 테스트는 공짜 이상이다

학습 테스트에 드는 비용은 없다. 어쨌든 API를 배워야 하므로. 학습 테스트는 이해도를 높여주는 정확한 실험이다. 

  학습 테스트는 공짜 이상이다. 투자하는 노력보다 얻는 성과가 더 크다. 패키지 새 버전이 나온다면 학습 테스트를 돌려 차이가 있는지 확인한다. 이런 경계 테스트가 있다면 패키지의 새 버전으로 이전하기 쉬워진다. 그렇지 않다면 낡은 버전을 필요 이상으로 오랫동안 사용하려는 유혹에 빠지기 쉽다. 

 

아직 존재하지 않는 코드를 사용하기

경계와 관련해 또 다른 유형은 아는 코드와 모르는 코드를 분리하는 경계다. 때로는 우리 지식이 경계를 너머 미치지 못하는 코드 영역도 있다. 때로는 더 이상 내다보지 않기로 결정한다. ( 적어도 지금은 )

 

구현을 나중으로 미루고, 이쪽 코드를 진행하고자 자체적으로 인터페이스를 정의했다. 

우리가 바라는 인터페이스를 구현하면 우리가 인터페이스를 전적으로 통제한다는 장점이 생긴다. 또한 코드 가독성도 높아지고 코드 의도도 분명해진다. 

송신기 API가 정의된 후에는, Adapter를 이용하여 간극을 메운다. 

 

깨끗한 경계

- 소프트웨어 설계가 우수하다면 변경하는데 많은 투자와 재작업이 필요하지 않다. 엄청난 시간과 노력과 재작업을 요구하지 않는다. 

- 통제하지 못하는 코드를 사용할 때는 너무 많은 투자를 하거나 향후 변경 비용이 지나치게 커지지 않도록 각별히 주의해야 한다.

- 통제가 불가능한 외부 패키지에 의존하는 대신 통제가 가능한 우리 코드에 의존하는 편이 훨씬 좋다.