diff --git "a/3\354\236\245/\354\265\234\354\204\234\355\235\254.md" "b/3\354\236\245/\354\265\234\354\204\234\355\235\254.md" new file mode 100644 index 0000000..24a49df --- /dev/null +++ "b/3\354\236\245/\354\265\234\354\204\234\355\235\254.md" @@ -0,0 +1,67 @@ +# 3장. 함수 + +## 인상 깊은 내용 - 함수를 잘 만드는 법을 소개 + +- **한 가지만 해라!** + + 함수는 한 가지를 해야 한다. 그 한 가지를 잘 해야 한다. 그 한 가지만을 해야 한다. + 단순히 다른 표현이 아니라 의미 있는 이름으로 다른 함수를 추출할 수 있다면 그 함수는 여러 작업을 하는 셈이다. + +- **위에서 아래로 코드 읽기: 내려가기 규칙** + + 위에서 아래로 TO 문단을 읽어내려 가듯이 코드를 구현하면 추상화 수준을 일관되게 유지하기 쉬워진다. + +- **오류 코드보다 예외를 사용하라!** + + 오류 코드보다 예외를 사용하라! 명령 함수에서 오류 코드를 반환하는 방식은 명령/조회 분리 규칙을 미묘하게 위반한다. + 자칫하면 if 문에서 명령을 표현식으로 사용하기 쉬운 탓이다. + + > ```java + > if (deletePage(page) == E_OK) { + > if (registry.deleteReference(page.name) == E_OK) { + > if (configKeys.deleteKey(page.name.makeKey()) == E_OK) { + > logger.log("page deleted"); + > } else { + > logger.log("configKey not deleted"); + > } + > } else { + > logger.log("deleteReference from registry failed"); + > } + > } else { + > logger.log("delete failed"); + > return E_ERROR; + > } + > ``` + + 반면 오류 코드 대신 예외를 사용하면 오류 처리 코드가 원래 코드에서 분리되므로 코드가 깔끔해진다. + + > ```java + > try { + > deletePage(page); + > registry.deleteReference(page.name); + > configKeys.deleteKey(page.name.makeKey()); + > } catch (Exception e) { + > logger.log(e.getMessage()); + > } + > ``` + +- **오류 처리도 한 가지 작업이다.** + + 오류 처리도 한 가지 작업이다. 함수는 '한 가지' 작업만 해야 한다. + 오류 처리도 '한 가지' 작업에 속한다. + 그러므로 오류를 처리하는 함수는 오류만 처리해야 마땅하다. + + 함수에 키워드 try가 있다면 함수는 try 문으로 시작해 catch/finally 문으로 끝나야 한다는 말이다. + +## 💭 느낀 점 + + 가장 인상 깊었던 부분은 단연 **"한 가지만 해라!"** 라는 원칙이다. + 최근 한 현직자에게 컴포넌트 분리 기준에 대해 물어본 적이 있었는데, 그분도 같은 이야기를 했다. + + "하나의 파일이나 컴포넌트가 두 가지 이상의 역할을 하면 나눠야 한다." + + 이 원칙은 단순히 함수에만 적용되는 게 아니다. + **코드 전체의 구조, 설계, 나아가 팀의 개발 문화까지 관통하는 핵심 철학**이라고 느꼈다. + + 함수가 명확하면 모듈이 명확해지고, 모듈이 명확하면 시스템 전체가 깔끔해진다. + 그래서 이 원칙은 가장 단순하면서도 가장 강력한 원칙이라고 생각한다. diff --git "a/4\354\236\245/\354\265\234\354\204\234\355\235\254.md" "b/4\354\236\245/\354\265\234\354\204\234\355\235\254.md" new file mode 100644 index 0000000..ca5c2fe --- /dev/null +++ "b/4\354\236\245/\354\265\234\354\204\234\355\235\254.md" @@ -0,0 +1,72 @@ +# 4장. 주석 + +## 인상 깊은 내용 + +- **나쁜 코드에 주석을 달지 마라. 새로 짜라.** + +- **주석은 나쁜 코드를 보완하지 못한다.** + 표현력이 풍부하고 깔끔하며 주석이 거의 없는 코드가, 복잡하고 어수선하며 주석이 많이 달린 코드보다 훨씬 좋다. + 자신이 저지른 난장판을 주석으로 설명하려 애쓰는 대신에, 그 난장판을 깨끗이 치우는 데 시간을 보내라! + +- **코드로 의도를 표현하라!** + 많은 경우, 주석으로 달려는 설명을 함수로 만들어 표현해도 충분하다. + +- **좋은 주석** + +> 1. **법적인 주석** + 회사 정책이나 법적 요구에 따라 파일 상단에 들어가는 저작권, 소유권 정보 등은 타당하고 필요하다. +> 2. **정보를 제공하는 주석** + 가능하다면 함수 이름에 정보를 담는 편이 더 좋지만, 꼭 필요한 경우 주석으로 보완한다. +> 3. **의도를 설명하는 주석** +> 4. **의미를 명료하게 밝히는 주석** + 인수나 반환값이 외부 라이브러리에 속해 있어 변경할 수 없다면, 명료한 주석이 도움이 된다. +> 5. **결과를 경고하는 주석** +> 6. **TODO 주석** + 당장 구현할 수 없는 작업을 기록한다. + 예: 삭제 예정 기능, 리팩터링 요청, 추후 이벤트 대응 등 + 단, TODO가 시스템에 나쁜 코드를 남기는 핑계가 되어선 안 된다. + → **주기적으로 점검하고 제거하라.** +> 7. **중요성을 강조하는 주석** +> 8. **공개 API에서의 Javadocs** + +- **나쁜 주석** + +> 1. **주절거리는 주석** + 주석을 달기로 했다면, 제대로 써야 한다. 대충 써놓고 넘기지 말 것. +> 2. **같은 이야기를 중복하는 주석** +> 3. **오해할 여지가 있는 주석** +> 4. **의무적으로 다는 주석** + 모든 함수에 Javadocs, 모든 변수에 주석을 강요하는 규칙은 비효율적이다. +> 5. **이력을 기록하는 주석** +> 6. **있으나 마나 한 주석** + 너무 당연한 이야기를 반복하며 새로운 정보를 주지 못하는 주석 +> 7. **무서운 잡음** + 때로는 Javadocs도 잡음이 된다. +> 8. **함수나 변수로 표현할 수 있다면 주석을 달지 마라** +> 9. **위치를 표시하는 주석** +> 10. **닫는 괄호에 다는 주석** + 중첩이 심한 구조에서 의미가 있을 수 있지만, 작고 명확한 함수에는 불필요하다. + 닫는 괄호에 주석을 달고 싶다면, **함수를 더 작게 쪼개는 걸 먼저 고려하라.** +> 11. **공로를 돌리거나 저자를 표시하는 주석** + 이런 정보는 소스 코드 관리 시스템(Git 등)에 맡기는 게 낫다. +> 12. **주석으로 처리한 코드** +> 13. **HTML 주석** +> 14. **전역 정보** + 주석은 가능한 한 근처의 코드만 설명하라. + 시스템 전체를 설명하려는 주석은 혼란을 키운다. +> 15. **너무 많은 정보** +> 16. **모호한 관계** + 주석과 그 주석이 설명하는 코드 사이의 연결이 명확해야 한다. +> 17. **함수 헤더** + 짧고 명확한 함수는 긴 헤더 주석 없이도 충분하다. +> 18. **비공개 코드에서의 Javadocs** + 공개 API가 아니라면, Javadocs는 불필요한 경우가 많다. + +--- + +## 💭 느낀 점 + +이번 장에서는 **좋은 주석과 나쁜 주석**을 구분해 구체적으로 설명해줘서 매우 유용했다. +앞으로 주석을 달아야 할 일이 생긴다면, 이 기준을 참고해 더 신중하게 작성할 것이다. + +가장 핵심적인 포인트는, **"코드만으로 설명할 수 있다면 주석을 달지 않는 것이 최선"** 이라는 점이다.