Skip to content

Commit

Permalink
docs: 4장 백지연 추가 (#36)
Browse files Browse the repository at this point in the history
  • Loading branch information
100Gyeon authored Aug 13, 2024
1 parent 748ccb3 commit 85f0c95
Showing 1 changed file with 89 additions and 0 deletions.
89 changes: 89 additions & 0 deletions 4장/백지연.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,89 @@
# 4장 실용주의 편집증

실용주의 프로그래머는 어느 누구도, 심지어는 자기 자신도
완벽한 코드를 작성할 수 없음을 알기에 실수에 대비한 방어책을 마련한다.

## Topic 23 계약에 의한 설계

정직한 거래를 보장하는 방법 중 하나는 '**계약**'이다. (=자신과 상대편의 권리 및 책임)

**DBC(Design By Contract) : 계약에 의한 설계**
정확한 프로그램이란 자신이 하는 일보다 많지도 적지도 않게 '딱 그만큼만' 하는 프로그램이다.
이를 문서화하고 검증하는 것이 계약에 의한 설계의 핵심이다.

소프트웨어 시스템의 모든 함수와 메서드는 뭔가를 한다.
그 뭔가를 시작하기 전에 어떤 **전제 조건**을 가지고 있을 것이고, 루틴이 끝난 후에는 상태가 어떠할 것이라고 **선언**할 수 있다.

- 선행 조건 : 루틴의 요구 사항
- 후행 조건 : 루틴이 할 것이라고 보장하는 것, 루틴이 완료되었을 때 세상의 상태
- 클래스 불변식 : 조건이 언제나 참인 것을 클래스가 보장

계약에 부응하지 못하는 것은 **버그**다.
계약에 부응하기 위해서는 **게으름뱅이 코드**를 짜야 한다.
= 수용할 것은 엄격하게 확인하고, 내어 줄 것에 대해서는 최소한도를 약속

DBC는 일찍 멈추라는 개념과 잘 어울린다.
선행 조건, 후행 조건, 불변식을 검증하면 더 일찍 멈추고, 문제에 대한 정보를 알려줄 수 있다.
문제를 찾고 원인을 밝히기 위해서는 사고가 난 지점에서 일찍 멈추는 것이 유리하다.

호출하는 쪽과 호출되는 루틴 중에 선행 조건을 확인하는 것은 누구의 책임인가?
명시적으로 검증해야 할 매개 변수가 하나라도 있다면, **호출자가 검증을 수행해야 한다.**
호출되는 루틴은 선행 조건을 위배하는 매개 변수를 보지 못할 것이기 때문이다.

## Topic 24 죽은 프로그램은 거짓말을 하지 않는다

문제를 빨리 발견하면 좀 더 일찍 시스템을 멈출 수 있으니 더 낫다.
프로그램을 멈추는 것이 최선일 수도 있다.

얼랭과 같은 환경에서는 **프로그램이 실패하면 멈추도록 설계**되어 있는데, 이런 **실패는 슈퍼바이저가 관리**한다.
슈퍼바이저 자체가 실패하면 어떻게 될까? 슈퍼바이저의 슈퍼바이저가 실패를 관리한다.
이렇게 슈퍼바이저가 층층이 '**슈퍼바이저 트리**'를 이루는 설계로 이어진다.
이 기법은 고가용성, 결함 감내 시스템에서 얼랭이나 엘릭서를 채택하는 요인이 된다.

> '슈퍼바이저도 실패하면?'을 생각하고 있었는데 바로 몇 줄 뒤에 슈퍼바이저 트리를 설명하고 있어서 웃겼네요
> 이 부분 좀 흥미로웠습니다👍
반면 어떤 환경에서는 실행 중인 프로그램을 그냥 종료해 버리는 것이 적절하지 않을 수도 있다.
ex. 해제되지 않은 리소스, 로그 메시지 기록, 열려 있는 트랜잭션 정리, 다른 프로세스와의 상호작용

그럼에도 불구하고 있을 수 없는 일이 발생한 프로그램은 유효하지 않다는 기본 원칙은 똑같다.
죽은 프로그램이 끼치는 피해 < 이상한 상태의 프로그램이 끼치는 피해
되도록 빨리 종료하는 게 좋다.

## Topic 25 단정적 프로그래밍

절대 그런 일이 일어나지 않을 거라는 생각이 든다면 이를 확인하는 코드를 작성하라. = **단정문**(assertion)을 사용해라.
하지만 진짜 오류 처리가 필요한 곳에 단정을 대신 사용하지는 말라.
단정은 결코 일어나면 안 되는 것들을 검사한다.

> 절대 일어나지 않을 일인데 확인하는 게 저만 비효율적으로 느껴지나요?
> 아직 저한테 와닿는 토픽은 아니네요🤔
## Topic 26 리소스 사용의 균형

리소스 할당과 해제를 다루는 방침 소개

- 리소스를 할당하는 함수나 객체가 해제까지 책임져야 한다.
- 한 번에 여러 리소스를 사용하는 경우
- 참조가 망가지지 않도록 리소스를 할당한 순서의 역순으로 해제해라.
- 여러 코드에서 동일한 구성의 리소스를 할당하는 경우에는 같은 순서로 할당해야 교착을 막을 수 있다.

> 자바스크립트를 사용하면서 메모리를 크게 신경 쓰지 않았던 것 같아 반성하는 마음으로 관련 아티클을 읽었습니다..^^
> [자바스크립트 메모리 관리: 일반적인 메모리 누수를 방지하고 성능을 개선하는 방법](https://ykss.netlify.app/translation/javascript_memory_management)
> [교묘한 리액트 메모리 누수 - 리액트 컴파일러가 당신을 구하지 못하는 이유](https://emewjin.github.io/react-compiler-closure-performance)
> 얼마 전에 기능 구현하면서 `MutationObserver`, `IntersectionObserver`를 사용했는데
> `disconnect`를 통해 리소스를 해제했던 게 떠오르네요
## Topic 27 헤드라이트를 앞서가지 말라

자주 작은 단계들을 밟고, 더 진행하기 전에 피드백을 확인하고 조정하라.
반대로 큰 작업은 무엇일까? '예언'을 해야 하는 모든 작업이다.
자동차 헤드라이트로 비출 수 있는 거리에 한계가 있는 것처럼 우리도 한두 단계 앞의 미래만 내다볼 수 있다.
끽해야 며칠 정도일 것이고, 그 너머는 무모한 억측의 영역이다.
볼 수 있는 미래까지만 고려해야 한다.
미래가 어떤 모습일지 더 많이 예측하려 할수록 틀릴 가능성은 계속 높아질 것이다.
**불확실한 미래에 대한 설계를 하느라 진을 빼는 대신, 언제나 교체 가능한 코드를 작성해 대비하면 된다.**

> 너무 공감되는 토픽이네요 저는 예언하면서 코딩하는 사람과 협업하기 힘들더라구요
> '나중에 혹시 모르니까' 하면서 무리하게 구조를 변경할 이유가 없다고 생각합니다

0 comments on commit 85f0c95

Please sign in to comment.