Books/실용주의 프로그래머

4장. 실용주의 편집증

유로띠 2022. 3. 25. 01:54
반응형

안녕하세요 😀

 유로띠 입니다 😉

 

 

 

 

 

 

실용주의 프로그래머


TIL (Today I Learned)

3줄 요약

 

✏️  완벽한 소프트웨어는 만들 수 없어.. 안전한 소프트웨어를 만들자.

✏️  망치지 말고 멈춰!

✏️  이상적이지만 언제나 교체 가능한 코드를 작성하여 대비하자.

 

DAY 4

오늘 읽은 범위: 4장 실용주의 편집증

 

😉 책에서 기억하고 싶은 내용을 써보세요.

여러분은 완벽한 소프트웨어를 만들 수 없다.

🟢  실용주의 프로그래머는 자기 자신 역시 믿지 않는다. 자신의 실수에 대비한 방어책을 마련한다. (P.146)

🟢  불완전한 시스템, 어림도 없는 기간, 우스꽝스러운 도구, 불가능한 요구사항으로 가득 찬 세상에서 안전하게 살아 보자 (P.147)

 

계약에 의한 설계

🟢  DBC - 계약에 의한 설계(Design By Contract) (P.148)

      선행 조건

      루틴이 호출되기 위해 참이어야 하는 것.

      후행 조건

      루틴이 자기가 할 것이라고 보장하는 것.

      클래스 불변식

      호출자의 입장에서 볼 때는 이 조건이 언제나 참인 것을 클래스가 보장한다.

🟢  자신이 하는 일이라고 주장하는 것보다 많지도 적지도 않게 딱 그만큼만 하는 프로그램이다. 이 주장을 문서화하고 검증하는 것이 '계약에 의한 설계'의 핵심이다. (P.148)

🟢  만약 호출자가 루틴의 모든 선행 조건을 충족한다면 해당 루틴은 종료 시 모든 후행 조건과 불변식이 참이 되는 것을 보장한다. (P.149)

 

글보다 예시를 보면 더 이해하기가 쉽다.

 

✅  예금을 처리하는 예시

선행 조건(pre) : 금액이 0보다 커야 한다, 계좌가 개설되어 있어야 한다.

후행 조건(post) : 반환하는 값인 새로운 거래를 이 계좌의 거래 목록에서 찾을 수 있다.

(defn accept-deposit [account-id amount]
    { :pre [ (> amount 0.00)
    		 (account-open? account-id) ]
      :post [ (contains? (account-transactions account-id) %) ] }
    "입금을 처리하고 거래 id를 반환"
    ;; 이런저런 처리를 수행...
    ;; 새로 거래를 만들어서 반환.
    (create-transaction account-id :deposit amount))

 

계약으로 설계하라.

🟢  게으름뱅이코드 - 시작하기 전에 자신이 수용할 것은 엄격하게 확인하고, 내어 줄 것에 대해서는 최소한도를 약속하는 것이다. (P.151)

 

DBC 구현

🟢  코드를 작성하기 전에 유효한 입력 범위가 무엇인지, 경계 조건이 무엇인지, 루틴이 뭘 전달한다고 약속하는지, 혹은 더 중요하게는 무엇을 약속하지 않는지 등을 나열하는 것만으로도 더 나은 소프트웨어를 작성하는 데에 엄청난 도움이 된다. (P.153)

🟢  일찍 작동을 멈춰라 (P.154)

🟢  문제를 찾고 원인을 밝히기 위해서는 사고가 난 지점에서 일찍 멈추는 것이 유리하다. (P.155)

🟢  의미론적 불변식은 무언가가 품은 진짜 의미의 중심이 되어야 하며, 훨씬 역동적으로 변하는 비즈니스 규칙처럼 일시적인 정책에 영향을 받으면 안 된다. 우리가 의미론적 불변식이라는 용어를 사용하는 것은 이 때문이다. (P.156)

🟢  죽은 프로그램은 거짓말을 하지 않는다. (P.158)

 

try do
  add_score_to_board(score);
rescue InvalidScore
  Logger.error("올바르지 않은 점수는 더할 수 없음. 종료합니다");
  raise
rescue BoardServerDown
  Logger.error("점수를 더할 수 없음: 보드가 죽었음. 종료합니다");
  raise
rescue StaleTransaction
  Logger.error("점수를 더할 수 없음: 오래된 트랜잭션. 종료합니다);
  raise
end

실용주의 프로그래머라면 다음과 같이 쓸 것이다.

add_score_board(score);

 

🟢  애플리케이션 코드가 오류처리 코드 사이에 묻히지 않는다. 두 번째 이유는 코드의 결합도를 높이지 않는다는 점이다. (P.160)

🟢  일찍 작동을 멈춰라. 망치지 말고 멈춰라 (P.160)

🟢  방어적 프로그래밍은 시간 낭비다. 그냥 멈추는 게 낫다. 일반적으로 죽은 프로그램이 끼치는 피해는 이상한 상태의 프로그램이 끼치는 피해보다 훨씬 적은 법이다. (P.161)

 

단정적 프로그래밍

🟢  그런 일은 절대 일어날 리 없어. 이런 식으로 자신을 기만하지 말자, 특히 코딩할 때는. (P.162)

🟢  진짜 오류 처리를 해야 하는 곳에 단정을 대신 사용하지는 말라. 단정은 결코 일어나면 안 되는 것들을 검사한다. (P.163)

 

리소스 사용의 균형

🟢  중첩 할당 시 리소스를 할당한 순서의 역순으로 해제하라. 코드의 여러 곳에서 동일한 구성의 리소스들을 할당하는 경우에는 언제나 같은 순서로 할당해야 교착 가능성을 줄일 수 있다. (P.171)

 

헤드라이트를 앞서가지 말라

🟢  작은 단계들을 밟아라. 언제나. (P.178)

🟢  불확실한 미래에 대비한 설계를 하느라 진을 빼는 대신 언제나 교체 가능한 코드를 작성하여 대비하면 된다. 설사 여러분이 미래에 대한 확신이 있더라도 저 모퉁이 너머에 블랙 스완이 기다리고 있을 수 있다. (P.179)

 

 

🧐 오늘 익은 소감은? 떠오르는 생각을 가볍게 적어보세요

✅  DBC의 설계 방식을 응용하여 TDD를 한다면 보다 좋은 테스트 설계가 가능할 것 같다. 계약의 의한 설계(DBC)를 읽어보면 맞는지 모르겠지만 단일 책임 원칙이 떠오른다.

많지도 적지도 않게 딱 자신의 책임만 하면 되기에..

 

✅  망치지 말고 멈춰. 실제론 애플리케이션을 종료시킬 수 없지만 계속해서 버그를 만드는 것보다는 중지시키고 원인을 찾아 해결하는 것이 더 낫다는 생각이 든다.

실제로 강의의 시청 기록을 저장하는 부분을 패치하다가 강의는 문제없이 시청하지만 시청 기록을 저장하지 못하는 버그가 발생되었다.

약 20여분 정도 후에 알게 되어 급히 핫픽스를 진행했지만, 그 시간 동안 처리되지 못하는 사용자는 대략 1000여 명 정도이다.

만약, 어떠한 버그로 멈춰서 시청이 아예 안되었다면 버그를 빨리 찾아서 핫픽스를 진행했을 것이고 시청기록의 누락도 발생하지 않았을 것이다.

물론 어느 쪽이 피해가 큰지는 확인해야겠지만.. 

 

✅  정말 일어날 수 없는 일은 없다고 생각한다. 책에서도 몇 번 강조하였지만, 코드에 대해 자신을 가지되, 자만하지는 말자.

 

✅  코드를 작성할 때 항상 교체 가능한 코드를 작성하면 정말 이것만큼 이상적인 것은 없다고 생각한다. 매번 코드를 작성할 때마다 그놈의 결합도가 높아지고 걷어 내려고 하면 얽히고설키고 스파게티처럼 꼬여있는 코드를 발견하게 된다. 항상 생각하자. 교체 가능한 코드!

 

🙋‍♂️ 궁금한 내용이 있거나, 잘 이해되지 않는 내용이 있다면 적어보세요.

 

 

반응형