책의 내용 중 자극히 개인적으로 중요한, 기억하고 싶은 부분들을 메모해두자. 자세한 내용은 책을 참고하자.
- 고품질의 코드는 개발자의 역량과 리더십의 지원, 두 가지가 다 있어야 가능한 성과물이기 때문에, 개발 조직의 리더가 개발과 테스트를 고려해서 충분한 시간을 보장해주어야 한다.
Chapter1. Code quality
- 고품질의 코드는 신뢰할 수 있고, 유지보수가 쉬우며, 요구 사항을 충족하는 소프트웨어가 될 가능성을 최대한으로 높여준다.
실제 서비스되는 환경에서 실행되는 소프트웨어가 되기까지의 과정
- 개발자가 코드베이스(Git과 같은 형상 관리 시스템)의 로컬 복사본을 가지고 작업하면서 코드를 변경한다.
- 작업이 끝나면 코드 검토를 위해 변경된 코드를 가지고 병합 요청을 한다.
- 다른 개발자가 코드를 검토하고 변경을 제안할 수 있다.
- 작성자와 검토자가 모두 동의하면 코드가 코드베이스에 병합된다.
- 배포는 코드베이스를 가지고 주기적으로 일어나지만, 얼마나 자주 배포되는지는 조직과 팀마다 다를 수 있다.
- 테스트에 실패되거나 코드가 컴파일되지 않으면 코드베이스에 병합되는 것을 막거나 코드가 배포되는 것을 막는다.
코드를 작성할 때 다음과 같은 네 가지 상위 수준의 목표를 달성해야 한다.
- 작동해야 한다.
- 작동을 멈춰서는 안된다.
- 변화하는 요구 사항에 적응해야 한다.
- 이미 존재하는 기능을 또다시 구현해서는 안된다.
코드 품질
의 여섯 가지 핵심 요소는 다음과 같다.
- 코드는 읽기 쉬워야 한다.
- 코드는 예측 가능해야 한다.
- 코드를 오용하기 어렵게 만들라.
- 코드를 모듈화해라.
- 코드를 재사용 가능하고 일반화할 수 있게 작성하라.
- 테스트가 용이한 코드를 작성하고, 제대로 테스트하라.
Chapter2. Layers of abstraction
Method
-
단일 함수 내에서 너무 많은 작업을 수행하면 코드를 이해하기 어렵게 만드는 문제가 발생할 수 있다.
-
그러한 문제가 발생한다면 함수를 작게 만들고 수행하는 작업을 명확하게 해서 코드의 가독성과 재사용성을 높힌다.
Class
줄 수
(number of lines): ‘한 클래스는 코드 300 줄을 넘기지 않아야 한다’와 같은 가이드라인을 접하는 경우가 있는데, 이는 경고의 역할만 할 뿐, 본인이 속한 팀의 문화에 따라 다를 수 있다.
응집력
(cohesion): 한 클래스 내의 모든 요소들이 얼마나 잘 속해 있는지를 보여주는 척도로, 좋은 클래스는 응집력이 매우 강하다. 응집력에는 여러 방식이 있다.
- 예를 들어, 커피 한 잔을 만드는 과정(원두를 갈아서 커피를 추출하는)과 같은
순차적 응집력
이 있고, 케이크를 만들기 위해 필요한 장비를 모이는 과정과 같은기능적 응집력
이 있다.
관심사의 분리
(seperation of concerns): 시스템이 각각 별개의 문제를 다루는 개별 구성 요소로 분리되어야 한다고 주장하는 설계 원칙이다.
-
코드를 적절한 크기의 클래스로 쪼개지 않으면 너무 많은 개념을 한꺼번에 다루고,
-
그로 인해 가독성이 떨어지며 모듈화가 덜 이루어지고,
-
재사용과 일반화가 어렵고, 테스트하기도 어려워진다.
Interface
-
하나의 추상화 계층에 대해 두 가지 이상의 다른 방식으로 구현을 하거나 향후 다르게 구현할 것으로 예상되는 경우 인터페이스를 정의하는 것이 좋다.
-
이를 통해 코드를 더욱 모듈화할 수 있고 재설정도 훨씬 쉽게 할 수 있다.
모든 것을 위한 인터페이스?
-
주어진 추상화 계층에 대해 하나의 구현만 존재하는 경우에도 인터페이스를 통해 추상화 계층을 표현해야 하는지는 팀에서 결정할 문제다.
-
많은 소프트웨어 공학 철학에서는 인터페이스 사용을 권장하지만, 나는 조금 다른 생각을 가지고 있다.
-
나의 경우, 두 가지 이상의 구현이 있거나 앞으로 다른 구현이 필요할 가능성이 있는 경우가 아니라면, 단 하나의 구현 클래스만 있다면 굳이 인터페이스를 만들 필요는 없다고 본다.
-
인터페이스와 구현 클래스가 1:1로 대응될 때는 서비스가 확장될수록 관리해야 할 파일과 코드가 불필요하게 많아지기 때문이다.
-
또한, 다른 개발자가 코드를 이해하려고 할 때, 인터페이스 -> 구현 클래스(하위) 로 이동하면서 찾아야 한다.
-
그래서 나는 일반적으로 먼저 구현 클래스로 시작하고, 인터페이스가 필요한 시점에 도입하여 설계를 보완해 나가는 방식을 선호한다.
-
-
일반적으로 클래스를 작성하거나 수정해야 할 때, 인터페이스를 붙이는 것이 어렵지 않도록 코드를 작성해야 한다.