📘 1장 :: 깨끗한 코드
"코드가 존재하리라"
DSL(Domain Specific Language) : 도메인에 특화된 언어, 특정 문제 해결 기법에 사용할 목적으로 만든 프로그래밍 언어나 명세 언어를 의미한다.
"나쁜 코드"
르블랑의 법칙 : 나중은 결코 오지 않는다. 나중에 손 보겠다고 한 코드, 돌아간다는 사실에 안도감을 느끼고 위로하며 결국에는 고치지 않는다.
"나쁜 코드로 치르는 대가"
"보이스카우트 규칙"
캠프장은 처음 왔을 때보다 더 깨끗하게 해 놓고 떠나라. ⇒ 지속적인 개선
"설계 원칙"
◾ SRP(Single Responsibility Principle): 클래스에는 단 한 가지 변경 이유만 존재해야 한다.
◾ OCP(Open Closed Principle): 클래스는 확장에 열려있어야 하며 변경에 닫혀있어야 한다.
◾ LSP(Liskou Subsitution Principle): 상속받은 클래스는 기초 클래스를 대체할 수 있어야 한다.
◾ DIP(Depending Inversion Principle): 추상화에 의존하라, 구체화하지 마라
◾ ISP(Interface Seregation Principle): 클라이언트에 밀접한 작게 쪼개진 인터페이스를 유지하라
📘 2장 :: 의미 있는 이름
◾ 불용어를 지양하고 구체적인 단어의 사용하라
- theUserData - userData, user - userInfo - userDate
◾ 발음하기 쉬운 이름을 사용하라
◾ 검색하기 쉬운 이름을 사용하라
- 긴 이름 > 짧은 이름, 상수는 변수에 할당하여 사용
◾ 인코딩을 피하라
- 불필요한 정신적 부담은 피하라
- 접두어는 버려라
◾ 자신의 기억력을 자랑하지 마라 (p.31)
◾ 기발한 이름은 피하라
◾ 한 개념에 한 단어를 사용하라
◾ 해법 영역에서 가져온 이름을 사용하라(p.34)
- 코드를 읽을 사람은 개발자 이므로 기술용어를 이름으로 하는데 거부감을 갖지 말라.
◾ 문제 영역에서 가져온 이름을 사용하라(p.34)
◾ 의미 있는 맥락을 추가하라, 불필요한 맥락을 없애라
=========================>>>>>>
모든 것에 이름은 중요하다. 따라서 이름을 잘 지어야 한다.
그렇다면 의도가 분명한 네이밍이란? -> 모호하다. 어느 게 의도가 분명한 거지?
책에서는 위와 같이 여러 제안을 던져준다. 하지만 그 안에서 반대되는 말을 할 때가 있다.
공통적으로 나오는 것은, 일관성 있고 명확한 역할을 하는 단어의 이름을 선택하라는 것이며 짧은 이름보다는 긴 이름이 낫다는 것이다.
또한, 코드를 읽을 사람 또한 개발자 이므로 때로는 기술용어를 이름으로 하는데 거부감을 갖지 말라는 말도 있다.
기억할만하다고 생각한 것은 31~33페이지에 있는 내용이다.
📘 3장 :: 함수
함수를 잘 만드는 방법
◾ 가능한 작게 만들어라
- 블록과 들여쓰기: 중첩문안에서도 작은 함수를 호출하도록 하면 좋다.
◾ 한 가지만 해라
- 하나의 함수는 한 가지의 역할만 해야 하며,
여러 역할을 할 경우 다른 함수를 만들어 사용함으로써 재사용성과 추상화 수준을 높인다.
◾ 위에서 아래로 자연스럽게 읽히는 함수를 만들어라
◾ 서술적인 이름을 사용하라
- "코드를 읽으면서 짐작했던 기능을 각 루틴이 그대로 수행한다면 깨끗한 코드라 불러도 된다"
◾ 함수 인수
- 인수는 가능한 적을수록 이상적이다.
◾ 명령과 조회를 분리하라
- 이 말 역시 하나의 기능만 하라는 말이다.
◾ 오류 코드보다 예외를 사용하라
- if문을 통해 오류 코드를 체크하는 것보다 try-catch를 이용한 예외처리를 한다.
◾ 반복하지 마라
- 중복은 소프트웨어에서 모든 악의 근원이다.
- 구조적 프로그래밍, AOP, COP 모두 어떤 면에서는 중복 제거 전략이다.
◾ 구조적 프로그래밍
- 데이크스트라 "모든 함수와 함수 내 모든 블록에 입구와 출구가 하나만 존재해야 한다"
- return는 하나여야 한다, 루프에서 break / continue를 사용해서는 안된다.
- 그럼에도 불구하고 함수가 작다면 위의 규칙은 큰 이익을 제공하지 못한다.
따라서 꼭 지켜야 하는 규칙이 아니며 때로는 장점을 줄 수도 있다.
=========================>>>>>>
일단 함수를 작성한 후 계속해서 다듬어 나감으로써 좋은 함수를 만들 수 있다.
📘 4장 :: 주석
"나쁜 코드에 주석을 달지 마라. 새로 짜라"
"주석은 기껏해야 필요 악이다."
- 코드로 의도를 표현하지 못해 주석을 사용한다. 즉, 주석은 실패를 의미한다.
- 주석은 나쁜 코드를 보완하지 못한다.
- 주석을 쓸 시간을 나쁜 코드를 보완하는데 써라
======> 함수를 설명하는데 주석을 썼었는데 함수 이름을 명확하게 하면 주석을 쓸 필요가 없어진다.
"좋은 주석"
- 법적인 주석
- 정보를 제공하는 주석
- 의도를 설명하는 주석
- 의미를 명료하게 밝히는 주석
- 결과를 경고하는 주석
- TODO 주석
- 중요성을 강조하는 주석
"나쁜 주석"
- 주절거리는 주석
- 같은 이야기를 중복하는 주석
- 오해할 여지가 있는 주석
- 의무적으로 다는 주석
- 이력을 기록하는 주석
- 있으나 마나 한 주석
- 무서운 잡음
- 함수나 변수로 표현할 수 있다면 주석을 달지 마라
- 위치를 표시하는 주석
- 닫는 괄호에 다는 주석
- 공로를 돌리거나 저자를 표시하는 주석
- 주석으로 처리한 코드
- HTML주석
- 전역 정보
- 너무 많은 정보
- 모호한 관계(추가적인 설명을 요구하는 주석)
- 함수헤더
- 비공개 코드에서의 Javadocs
=========================>>>>>>
4장의 핵심 문구
"나쁜 코드에 주석을 달지 마라. 새로 짜라"
"주석은 기껏해야 필요악이다." - p.68
- 코드로 의도를 표현하지 못해 주석을 사용한다. 즉, 주석은 실패를 의미한다.
- 주석은 나쁜 코드를 보완하지 못한다.
- 주석을 쓸 시간을 나쁜 코드를 보완하는데 써라
평소 함수명 위에 주석으로 해당 함수에 대해 간략하게 주석을 달았었는데
주석 없이 의미가 전달되는 함수명을 짓도록 노력해야겠다.
그리고 나쁜 주석에서 기억이 남는 건
- 공로를 돌리거나 저자를 표시하는 주석 ---> 코드 관리 시스템을 믿어라
- 주석으로 처리한 코드 ---> 코드 관리 시스템을 믿어라
인데, 나중에 기억이 안 날까 봐 주석처리를 해놓는 게 좀 많은데 버전관리를 믿고 과감히 삭제하도록 해야겠다.
📘 5장 :: 형식 맞추기
프로그래머라면 형식을 깔끔하게 맞춰 코드를 짜야한다.
코드 형식을 맞추기 위한 간단한 규칙을 정하고 그 규칙을 착실히 따라야 한다.
"형식을 맞추는 목적"
- 코드 형식은 의사소통의 일환이며, 의사소통은 전문 개발자의 일차적인 의무이다.
- '돌아가는 코드'는 기능 변경에 의해 버려질 수 있지만, 의사소통이 되는 코드는 유지보수의 용이성과 확장성에 영향을 미친다.
"적절한 행 길이를 유지하라"
- 신문 기사처럼 작성하라
- 개념은 빈 행으로 분리하라
- 세로 밀집도
- 수직거리
변수선언: 변수는 사용하는 위치에 최대한 가까이 선언한다.
인스턴스변수: 클래스 맨 처음에 선언한다.
종속함수: 한 함수가 다른 함수를 호출한다면 두 함수는 최대한 가까이 배치한다.
또한, 호출하는 함수는 호출되는 함수보다 먼저 배치한다.
개념적 유사성: 개념적 친화도가 높은 코드는 가까이 배치한다.(변수와 함수, 종속함수...)
- 세로 순서(고차원→저차원)
"가로 형식 맞추기"
추천하는 행 길이는 120자
- 가로 공백과 밀집도: 공백은 강조의 의미 또는 다른 개념의 분리
- 가로 정렬: 불필요한 정렬은 정작 중요한 부분을 놓치게 한다. p.109
- 들여 쓰기: 들여 쓰기가 없다면 인간이 코드를 읽기란 거의 불가능할 것이다. 구조파악↑
- 가짜범위:
"팀 규칙"
=========================>>>>>>
코드를 작성하는 스타일을 개발자마다 다른 게 당연하다.
하지만 그럼에도 불구하고 코딩 컨벤션을 맞추는 건 어딜 가나 중요하다고 생각한다.
그런 점에서 저번에 말한 우리의 코딩 컨벤션은?
- 코드 형식은 의사소통의 일환이며, 의사소통은 전문 개발자의 일차적인 의무이다.
- '돌아가는 코드'는 기능 변경에 의해 버려질 수 있지만, 의사소통이 되는 코드는 유지보수의 용이성과 확장성에 영향을 미친다.
📘 6장 :: 객체와 자료 구조
객체는 내부 구조를 숨겨야 하고, 자료 구조는 내부 구조를 노출한다.
"자료 추상화"
- 자료를 세세하게 공개하기보다는 추상적인 개념으로 표현하는 편이 좋다.
- 인터페이스에 조회와 설정 함수가 같이 있는 경우 구현을 외부로 노출한 것이다.
- 인터페이스나 조회/설정 함수만으로는 추상화가 이루어지지 않는다.
아무 생각 없이 조회/설정 함수를 추가하는 방법이 가장 나쁘다.
"자료/객체 비대칭"
- 객체 지향 코드에서 어려운 변경은 절차적인 코드에서 쉬우며,
절차적인 코드에서 어려운 변경은 객체 지향 코드에서 쉽다.
- 새로운 자료 타입이 필요한 경우 객체 지향 기법이 적합하며,
새로운 함수가 필요한 경우 절차적인 코드와 자료 구조가 적합하다.
- 때로는 단순한 자료 구조와 절차적인 코드가 가장 적합한 상황도 있다.
"디미터 법칙"
- 모듈은 자신이 조작하는 객체의 내부를 몰라야 한다.
- [기차 충돌]
ctxt.getXXX().getXXX().getXXX();
→ ctxt.options.scratchDir.absoltePath;
- [잡종 구조]
절반은 객체, 절반은 자료 구조인 잡종.
새로운 함수는 물론이고 새로운 자료 구조도 추가하기 어렵다.(양쪽의 단점만 모아놓은 구조이다)
- [구조체 감추기]
ctxt.getAbsolutePathOfScratchDirectoryOption();
ctxt.getScratchDirectoryOption().getAbsolutePath();
→ ctxt.creatScratchFileStream(classFileName);
"자료 전달 객체"
- 자료 구조체의 전형적인 형태는 공개 변수만 있고 함수가 없는 클래스이다.
→ 이런 자료 구조체를 때로는 자료 전달 객체(Data Transfer Object, DTO)라고 한다.
→ DTO는 데이터베이스와 통신하거나 소켓에서 받은 메시지의 구문분석 시 유용하다.
→ 또한, 데이터베이스에 저장된 가공되지 않은 정보를 애플리케이션 코드에서 사용할 객체로 변환하는 단계에서
가장 처음으로 사용하는 구조체이다.
→ 일반적인 형태는 빈(Bean) 구조다.
→ 빈은 비공개 변수를 조회/설정 함수로 조작하며, 일종의 사이비 캡슐화이다.
- [활성 레코드]
활성 레코드는 DTO의 특수한 형태이다.
활성 레코드는 데이터베이스 테이블이나 다른 소스에서 자료를 직접 변환한 결과이다.
활성 레코드는 자료 구조로 취급한다.
비즈니스 규칙을 담으면서 내부 자료를 숨기는 객체는 따로 생성한다.(내부자료=활성 레코드의 인스턴스)
=========================>>>>>>
객체는 동작을 공개하고 자료를 숨긴다.
따라서 기존 동작을 변경하지 않으면서 새 객체 타입을 추가하기는 쉽지만, 기존 객체에 새 동작을 추가하는 것은 어렵다.
자료 구조는 별다른 동작 없이 자료를 노출한다.
따라서 기존 자료 구조에 새 동작을 추가하기는 쉬우나, 기존 함수에 새 자료 구조를 추가하기는 어렵다.
시스템을 구현할 때
새로운 자료 타입을 추가하는 유연성이 필요하면 객체가 적합하다.
새로운 동작을 추가하는 유연성이 필요하면 자료 구조와 절차적인 코드가 적합하다.
'Book Review' 카테고리의 다른 글
[Clean Code] 클린 코드 10장 ~ 11장 리뷰 (0) | 2023.02.03 |
---|---|
[Clean Code] 클린 코드 7장 ~ 9장 리뷰 (0) | 2023.01.26 |
최근댓글