원서 요약이므로 오역 및 잘못된 해석이 존재 할 수 있습니다.
소프트웨어의 복잡도는 어떻게 줄이고 어디에 둘 것인가에 관한 고민이 담긴 책
- 복잡도: 시스템과 관련된 무엇이든 시스템을 이해하고 수정하기 어렵게 만드는 것
- 복잡도가 높을 때 발생하는 현상
- 변경 증폭: 하나의 변경이 여러 곳의 수정으로 증폭되는 현상
- 인지 부하: task 하나를 수행하기 위해 알아야하는 정보량이 너무 많을 때
- 알 수 없는 미지: 무엇을 모르는지조차 모르는 최악의 상태
- 타협의 대가는 의존성과 미지로 나타난다
- 매 번 작은 시간이라도 디자인 개선을 해야 한다
- 최고의 선택보다는 red-flag를 없애는 방향으로 생각해 보자
- Module(method, variable) 의 복잡도 관리
- 구현은 복잡하더라도 interface는 쉽고 간결해야 한다
- 정보는 최대한 유출하지 않아야 한다. 입력과 출력 모두 필요한 것만 존재해야 한다
- 함께 변하는 정보라면 꼭 분해해야 할 필요는 없다. 정보와 상태를 공유한다면 분리하는게 오히려 나쁜 결과를 만든다
- 같은 클래스라도 중요한 정보 변경은 locallize 함수에 묶어두는 편이 좋다
- 일반적 모듈: 현재 필요보다 조금만 더 넓고 추상화 관점에서 자연스러운 모듈
- 특화 모듈: 가능한 higher layer로 올려야 한다. lower layer는 매커니즘을 제공하고 higher layer는 정책을 결정하도록 구현하라
- 어쩔 수 없이 필요한 복잡도는 가능하면 모듈 내부로 끌어 내려라.
- Exception 의 복잡도 관리
- 현재 구현에서 postcondition을 만족 시킬 수 있다면 에러를 발생시켜야 할 이유가 없다
- boundary condition 마저 에러로 처리하지 말고 자연스럽게 해결한다면 caller가 처리할 에러가 줄어든다
- Exception 구분에 의미가 없다면 하지 말고 오히려 묶는 편이 caller에게 불필요한 강요를 하지 않아 유용하다
- comment 의 필요성
- why, constraint, tradeoff, rationale(이유) 등등 코드가 나타내지 못하는 것을 설명하라
- code 와 comment가 서로 다른 정보를 제공해야 한다
- interface 의 주석은 상세 구현과 무관해야 한다
- 주석이 너무 길어진다면 설계를 의심해야 할 순간이다
- Consistency
- 일관성 있는 코드 스타일은 인지 부하를 감소시켜 복잡도를 낮추는 강력한 방법이다
- 같은 concept에는 같은 표현을, 다른 concept에는 다른 표현을 사용하라
- 본질적은 명확하지 않은 영역인 성능 최적화, 이벤트 콜백, 동시성, 에러 회복 등은 코멘트가 매우 유용하다
- 구현 상속은 최대한 피하라 → 숨겨진 의존성과 응결이 발생한다
- Decide
- 최적화는 근본적인 문제를 해결하는 것이 아니라면 반드시 측정이 선행되어야 한다
- 중요하고 일반적은 것은 interface로 최대한 노출하되 그외는 줄여야 한다
- 모듈에서는 너무 특별한 API 보다 본질적인 operation을 제공하려고 노력하라
- 즉 useCase와 나머지를 구분해보려고 해라
- 많은 caller가 반복 처리할 거 같은 문제는 module 내부로 끌어내려라
- 미래의 비용을 낮추기 위해 디자인하는 것이다!!!