Post

실용주의 프로그래머 읽어보기 2주차

실용주의 프로그래머 읽어보기 2주차

들어가며

이 포스트는 데이비드 토머스, 앤드류 헌트의 「실용주의 프로그래머」 Topic1 ~ 8까지 읽고 개인적으로 학습한 내용을 정리한 글입니다.

  • 책: 실용주의 프로그래머
  • 저자: 데이비드 토머스, 앤드류 헌트
  • 출판사: 인사이트
  • 챕터: Topic 9 ~ Topic 11

핵심 내용 정리

Topic 9.DRY: 중복의 해악

유지 보수를 하려면 사물의 표현 양식, 즉 애플리케이션에 표현되어 있는 지식을 찾아내고 또 바꿔야 한다 문제는 명세와 프로세스, 개발하는 프로그램 안에 지식을 중복해서 넣기 쉬워지므로, 애플리케이션이 출시되기 한참 전부터 유지 보수의 악몽이 시작된다

DRY: 반복하지 말라(Don’t Repeat Yourself)

DRY는 코드 밖에서도

  • DRY는 지식의 중복, 의도의 중복
    • 똑같은 개념을 다른 두 곳 두군데에서 표현하면 안 된다는 것

모든 코드 중복이 지식의 중복은 아니다

  • 코드는 중복이지만, DRY 위반은 아니다
    • 두 함수는 각각 서로 다른 것을 검증하고 있지만, 우연히 규칙이 같은 것 뿐 => 즉, 중복은 아니지만 우연
      1
      2
      3
      4
      5
      6
      
      def validate_age(value):
        validate_type(value, integer)
        validate_min_integer(value,1)
      def validate_quantity(value):
        validate_type(value, integer)
        validate_min_integer(value,1)
      

문서화 중복

  • 모든 것에 주석을 달 필요는 없다
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    
    # 계좌의 수수료를 계산한다
    # * 반려된 수표 하나당 $20
    # 계좌가 3일 넘게 마이너스이면 하루에 $10 부과
    # 평균 잔고가 $2000보다 높으면 수수료 50% 감면
    def fees(a)
      f = 0
      if a.returned_check_count > 0
          f += 20 * a.returned_check_count
      end
      if a.overdraft_days > 3
          f += 10 * a.overdraft_days
      end
      if a.average_balance > 2_000
          f /= 2
      end
      f
    end
    
  • 이 함수의 의도가 주석으로 한 번, 코드로도 한 번 작성되어 있다

데이터의 DRY 위반

  • 자료 구조는 지식을 표현한다. 그리고 DRY 원칙을 위배할 수 있다
    1
    2
    3
    4
    5
    
    class Line {
      Point start
      Point end
      double length;
    }   
    
  • length는 start와 end가 정해지면 이미 결정되어 있다 => DRY 원칙을 위배한다
  • 모듈이 자료 구조를 노출하면 언제나 모듈의 구현과 그 자료 구조를 사용하는 코드 사이에 결합이 생긴다
    • 가능하다면 언제나 객체의 속성을 읽고 쓸 때 접근자 함수를 사용하라

표현상의 중복

  • 우리의 코드는 다른 서비스와의 원격 호출, 외부 저장소 등과 연결 => 일종의 DRY 위반을 하게 된다

내부 API에서 생기는 중복

  • 언어나 기술에 중립적인 형식으로 내부 API를 정의할 수 있는 도구를 찾아보라
    • 이런 도구는 일반적으로 문서와 mock API, 기능 테스트를 생성해 주고, API 클라이언트도 여러 가지 언어로 생성해준다

외부 API에서 생기는 중복

  • 공개 API를 OpenAPI 같은 형식으로 엄밀하게 문서화하는 경우 더욱 신뢰성 있는 서비스 연동이 가능해진다

데이터 저장소와의 중복

  • 많은 데이터 저장소에서 데이터 스키마 분석을 통해 데이터 저장소와 코드 간의 중복을 많이 제거할 수 있다
  • 때로는 코드에서 외부 데이터를 고정된 구조로 표현하는 대신, 키-값 데이터 구조(map, hash 등)로 밀어 넣는것이 도움이 된다

개발자 간의 중복

  • 가장 발견하기 어려운 중복은 개발자 간의 중복
  • 개발자 간의 중복에 대처하려면 크게는 의사소통을 잘하는 튼튼하고 유대가 돈독한 팀을 만들어야한다
  • 대화를 보존하고, 방해를 최소화하면서 의사소통 가능한 도구를 사용한다

Tip 16. 재사용하기 쉽게 만들어라

Topic 10. 직교성

직교성이란?

  • 일종의 독립성이나 decoupling
  • 하나가 바뀌어도 나머지에 어떤 영향도 주지 않으면 서로 직교한다고 할 수 있다

직교성의 장점

tip 17 관련 없는 것들 간에 서로 영향이 없도록 하라

  • 컴포넌트들이 각기 격리되어 있으면 어느 하나를 바꿀 때 나머지 것들을 걱정하지 않아도 된다
  • 직교적인 시스템은 생산성 향상과 리스크 감소에 이점이 있다

생산성 향상

  • 변화를 국소화해서 개발 시간과 테스트 시간이 줄어든다
  • 코드 재사용 촉진 -> 컴포넌트에 명확하고 잘 정의된 책임이 할당되어 있으면 애초의 구현자가 예상하지 못한 방식으로 새로운 컴포넌트와 결합할 수 있다
  • 직교적인 컴포넌트들을 결합하는 경우 얻을 수 있는 꽤 미묘한 생산성 향상 요소가 있다. 직교적인 컴포넌트들을 결합함으로써 단위 노력당 더 많은 기능을 얻을 수 있다

리스크 감소

  • 감염된 코드가 격리되면, 그 여파를 줄일 수 있고, 그 부분만 도려내고 새롭고 건강한 코드를 이식할 수 있다
  • 시스템이 잘 깨지지 않는다. 문제점이 문제 있는 부분만으로 한정할 수 있다
  • 직교적인 시슨템은 그 안의 컴포넌트에 대한 테스트가 수월하다
  • 외부 컴포넌트들에 덜 종속된다

설계

  • 시스템은 서로 협력하는 모듈의 집합으로 구성되어야 하고, 각 모듈은 다른 부분과 독립적인 기능을 구현해야 한다
  • 계층 구조 예시 계층 구조
  • 설계가 직교적인지 확인하는 질문들
    • ‘특정 기능에 대한 요구 사항을 대폭 변경하는 경우 몇 개의 모듈이 영향을 받는가?’ -> 직교적이라면 답이 ‘하나’ 여야한다

툴킷과 라이브러리

  • 툴킷이나 라이브러리를 도입할 때 코드에 수용해서는 안 될 변화를 강요하지 않는지 검토해야 한다
  • EJB는 내부를 바꾸지 않으면서 기능을 추구하는 decorator pattern의 예

코딩

직교성을 유지하기 위한 기법들

코드의 결합도를 줄여라

  • shy 코드를 작성하라.
  • 불필요한 것은 다른 모듈에 보여주지 않으며, 다른 모듈의 구현에 의존하지 않는 코드를 작성하라
  • 객체의 상태를 바꿀 필요가 있다면 자신을 위해 객체가 직접 상태를 바꾸게 하라

전역 데이터를 피하라

  • 코드가 전역 데이터를 참조할 때마다 코드는 해당 데이터를 공유하는 다른 컴포넌트와 묶이게 된다 일반적으로 필요한 컨텍스트를 모듈에 명시적으로 넘겨주면 코드를 이해하고 유지 보수하기 쉬워진다

유사한 함수를 피하라

  • 종종 유사해 보이는 함수를 여럿 구현해야할 때가 있다. 시작과 끝은 동일하지만 중간의 알고리즘이 다른 경우 일 경우, strategy pattern을 사용해 더 낫게 구현할 수 없는지 고민해봐야 한다

테스트

  • 직교적으로 설계하고 구현한 시스템은 테스트하기 더 쉽다
  • 단위 테스트를 작성하는 행위 자체가 직교성을 테스트해 볼 수 있는 기회다

문서화

  • 직교적인 문서라면 내용 변화 없이 모양새를 완전히 바꿀 수 있다

직교적으로 살아가기

  • DRY 원칙은 시스템 내부의 중복을 최소화하고, 직교성은 시스템 컴포넌트 간의 상호 의존도를 줄인다.
  • DRY 원칙으로 무장하고 직교성 원칙을 충실히 적용한다면 개발하고 있는 시스템이 더 유연하고 이해하기 쉬워진다
  • 디버깅, 테스트, 유지보수도 수월해진다

Topic 11. 가역성

Tip 18. 최종 결정이란 없다

가역성

  • DRY 원칙, 결합도 줄이기, 외부 설정 사용하기를 따르면 중요하면서도 되돌릴 수 없는 결정의 수를 가능한 한 줄일 수 있다
  • 되돌릴 수 없는 결정을 줄여야 하는 이유는 프로젝트 초기에 늘 최선의 결정을 내리지 못하기 때문이다
  • 결정이 바뀌지 않을 것이라 가정하고서 발생할지도 모를 우연한 사건에 대비하지 않는 데서 실수가 발생한다

유연한 아키텍처

다변하는 아키텍처 -> 아키텍처에 대한 계획을 세우는 것은 불가능하다

  • 지금까지 아키텍처의 변화
    • 거대한 iron(컴퓨터) -> 큰 쇳덩이를 많이 연결한 것 -> 일반 상용 하드웨어로 만든 클러스터들로 부하를 분산시키는 것 -> 애플리케이션을 구동하는 클라우드 기반 가상 머신 -> 서비스를 구동하는 클라우드 기반 가상 머신 -> 위의 것들을 컨테이너화 -> 클라우드 기반 서버리스 애플리케이션
    • 이 변덕스러운 환경에서 어떻게 계획을 세울 수 있는가 => 못한다
This post is licensed under CC BY 4.0 by the author.