목록클린코드 (11)
넘치게 채우기
모든 소프트웨어 시스템은 이해관계자에게 서로 다른 두 가지 가치를 제공하는데, 행위(behavior)와 구조(structure)가 있다. 소프트웨어 개발자는 두 가치를 모두 반드시 높게 유지해야 하는 책임을 가진다. 불행하게도 개발자는 한 가지 가치에만 집중하고 나머지 가치는 배제하곤 한다. 행위 소프트웨어의 첫 번째 가치는 바로 행위. 프로그래머는 이해관계자가 기능 명세서나 요구사항 문서를 구체화할 수 있도록 돕는다. 그리고 이해관계자의 기계가 이러한 요구사항을 만족할 수 있도록 돕는다. 기계가 이러한 요구사항을 위반하면, 프로그래머는 디버거를 켜고 문제를 고친다. 많은 프로그래머들은 이러한 활동이 자신이 해야 할 일의 전부라고 생각한다. 이들은 요구사항을 기계에 구현하고 버그를 수정하는 일이 자신의 ..
설계(design)와 아키텍처(architecture) 사이에는 오랫동안 많은 혼란이 있었다. 밥아저씨(로버트 C.마틴)의 첫 번째 주장: 둘 사이에는 차이가 없다. 보통 ‘아키텍처’는 저수준의 세부사항과는 분리된 고수준의 무언가를 가리킬 때 흔히 사용되는 반면, ‘설계’는 저수준의 구조 또는 결정사항 등을 의미할 때가 많다. 그러나, 아키텍트의 일을 살펴보면, 실제로 이러한 구분은 무의미하다. 새로운 집을 설계하는 아키텍트가 만든 도면에는 무수히 많은 저수준의 세부사항도 확인할 수 있다. 콘센트, 전등, 전등 스위치, 보일러와 온수기, 배출 펌프와 크기 등이 모두 어디에 위치해있는지 알 수 있다. 벽, 지붕, 기초 공사 역시 어떻게 진행되는지도 알 수 있다. 소프트웨어도 마찬가지이다. 저수준의 세부사항..
이 장에서는 깨끗한 클래스를 다룹니다. 클래스 체계 클래스를 정의하는 표준 자바 관리에 따르면, 가장 먼저 변수 목록이 나옵니다. 정적(static) 공개(public) 상수가 있다면 맨 처음에 나옵니다. 그 다음 정적 비공개(private) 변수, 이어서 비공개 인스턴스 변수가 나옵니다. 공개 변수가 필요한 경우는 거의 없습니다. 변수 목록 다음에는 공개 함수가 나옵니다. 비공개 함수는 자신을 호출하는 공개 함수 직후에 넣습니다. 즉, 추상화 단계가 순차적으로 내려갑니다. 그래서 프로그램은 신문 기사처럼 읽히는 것 입니다. 캡슐화 변수와 유틸리티 함수는 가능한 공개하지 않는 편이 낫지만, 반드시 숨겨야 한다는 법칙도 없습니다. 때로는 변수나 유틸리티 함수를 protected로 선언해 테스트 코드에 접근..
1997년만 해도 TDD(Test Driven Development)라는 개념을 아무도 몰랐습니다. 우리 대다수에게 단위 테스트란, 자기의 프로그램이 ‘돌아간다’라는 사실만 확인하는 일회성 코드에 불과했습니다. 지금은 애자일과 TDD 덕분에 단위 테스트를 자동화하는 프로그래머들이 이미 많아졌으며, 점점 늘어나는 추세입니다. TDD 법칙 세 가지 첫째 법칙 : 실패하는 단위 테스트를 작성할 때까지 실제 코드를 작성하지 않는다. 둘째 법칙 : 컴파일은 실패하지 않으면서 실행이 실패하는 정도로만 단위 테스트를 작성한다. 셋째 법칙 : 현재 실패하는 테스트를 통과할 정도로만 실제 코드를 작성한다. 위 세 가지 규칙을 따르면 개발과 테스트가 대략 30초 주기로 묶입니다. 테스트 코드와 실제 코드가 함께 나올뿐더러..
시스템에 들어가는 모든 소프트웨어를 직접 개발하는 경우는 드뭅니다. 패키지와 오픈 소스를 주로 이용하고, 때로는 사내 다른 팀이 제공하는 컴포넌트를 사용할 때가 있습니다. 우리는 어떤 식으로든 이 외부 코드를 우리 코드에 깔끔하게 통합시켜야만 합니다. 이 외부 코드를 내 코드에서 호출하는 부분을 경계(boundary)라고 합니다. 외부 코드 사용하기 인터페이스 제공자와 사용자 사이에는 특유의 긴장감이 존재합니다. 패키지 제공자나 프레임워크 제공자는 적용성을 최대한 넓히려고 애쓰지만, 사용자들은 자신의 요구에 맞는 인터페이스를 바랍니다. 예시로, java.util.Map을 살펴봅시다. Map은 수많은 기능을 제공하는 인터페이스인데, 여기에는 내용을 삭제하는 clear()라는 메서드도 있습니다. 이 말은, ..
오류 처리는 프로그램에 반드시 필요한 요소입니다. 상당수의 코드 기반은 전적으로 오류 처리 코드에 좌우됩니다. 여기서 좌우된다는 표현은 코드 기반이 오류만 처리한다는 의미가 아니라, 여기저기 흩어진 오류 처리 코드 때문에 실제 코드가 하는 일을 파악하기가 거의 불가능하다는 뜻입니다. 오류 처리로 인해 프로그램 논리를 이해하기 어려워진다면 깨끗한 코드가 불리기 어렵습니다. 이 장에서는 오류를 처리하는 기법과 고려 사항 몇 가지를 소개합니다. 오류 코드보다 예외를 사용하라 얼마 전까지만 해도 예외를 지원하지 않는 프로그래밍 언어가 많았습니다. public class DeviceController { ... public void sendShoutDown() { DeviceHandle handle = getHa..
변수를 비공개로 정의하는 이유는 남들이 변수에 의존하지 않게 만들기 위해서입니다. 그렇다면 어째서 get 함수와 set함수는 공개해서 외부에 노출할까요? 객체와 자료 구조 객체는 추상화 뒤로 자료를 숨긴 채 자료를 다루는 함수만 공개합니다. 자료 구조는 자료를 그대로 공개 하며 별다른 함수는 제공하지 않습니다. 둘은 상반된 관계입니다. 자료 추상화 추상화는 개발자가 객체의 구현 세부 사항에 신경 쓰지 않고도 객체의 기능에 집중할 수 있도록 해주는 중요한 개념입니다. 코드의 복잡성을 줄이고 가독성을 높이는 데 중요한 역할을 합니다. 데이터 추상화를 사용하면, 객체의 실제 구현 내용을 숨기고 사용자에게 필요한 기능만을 제공하는 인터페이스를 제공할 수 있습니다. 이를 통해, 객체의 내부 구현이 변경되더라도 사..
잘 달린 주석은 무엇보다도 유용합니다. 그러나, 경솔하고 근거 없는 주석은 코드를 이해하기 어렵게 만듭니다. 오래되고 조잡한 주석은 거짓과 잘못된 정보를 퍼트립니다. 우리는 코드로 모든 의도를 표현하지 못해, 그러니 실패를 만회하기 위해 주석을 사용합니다. 주석은 언제나 실패를 의미합니다. 의도는 코드만으로 표현될수록 깨끗합니다. 코드는 변화하고 진화합니다. 일부가 여기서 저기로 옮겨지기도 하고, 조각이 나뉘고 갈라지고 합쳐지고를 반복합니다. 주석까지 함께 유지보수되는 경우는 정말 드물고, 언제나 따라가지 않습니다. 부정확한 주석은 아예 없는 주석보다 훨씬 나쁩니다. 부정확한 주석은 독자를 현혹시킵니다. 그러나 진실은 코드에 있습니다. 코드만이 자기가 하는 일을 진실되게 말합니다. 그러므로 우리는 주석을..
작게 만들어라 함수를 만드는 첫 번째 규칙은 ‘작게!’ 입니다. 함수를 만드는 둘째 구칙은 ‘더 작게!’ 입니다. 함수에서의 들여쓰기 수준은 1단이나 2단을 넘어서면 읽기 매우 힘들어집니다. 한 함수에 많은 중첩 구조가 들어가지 않도록 해야합니다. 한 가지만 해라 “함수는 한 가지를 해야 한다. 그 한가지를 잘 해야 한다. 그 한가지만을 해야 한다.” 우리가 함수를 만드는 이유는 큰 개념을 다음 추상화 수준에서 여러 단계로 나눠 수행하기 위함입니다. 함수 당 추상화 수준은 하나로 함수가 확실히 ‘한 가지’ 작업만 하려면 함수 내 모든 문장의 추상화 수준이 동일해야 합니다. 한 함수 내에 추상화 수준을 섞으면 코드를 읽는 사람이 헷갈립니다. 특정 표현이 근본 개념인지 세부사항인지 구분하기가 어려워집니다. ..
소프트웨어에서 이름은 어디나 쓰입니다. 우리는 변수, 함수, 인수, 클래스, 패키지, 파일과 폴더 등 모두 이름을 붙입니다. 이렇게 많이 쓰이는 이름을 처음에 한 번 잘지으면 앞으로의 개발이 편해집니다. 의도를 분명히 밝혀라 좋은 이름을 만드는데에는 시간이 걸릴 수 있으나, 그로인해 앞으로 절약될 시간은 더 큽니다. 개발을 하다가도, 더 나은 이름이 생각나면 모두 바꾸십시오. 변수나 함수, 클래스의 이름은 존재 이유 수행 기능 사용 방법 을 주석 없이 표현할 수 있어야 합니다. int d; // 경과 시간(단위: 날짜) 보다 int elapsedTimeInDays; int daysSinceCreation; 와 같이 의도가 드러나는 이름을 사용하면 코드 이해와 변경이 쉬워집니다. 그릇된 정보를 피하라 널리..