목록개발/Clean Code (10)
넘치게 채우기
이 장에서는 깨끗한 클래스를 다룹니다. 클래스 체계 클래스를 정의하는 표준 자바 관리에 따르면, 가장 먼저 변수 목록이 나옵니다. 정적(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함수는 공개해서 외부에 노출할까요? 객체와 자료 구조 객체는 추상화 뒤로 자료를 숨긴 채 자료를 다루는 함수만 공개합니다. 자료 구조는 자료를 그대로 공개 하며 별다른 함수는 제공하지 않습니다. 둘은 상반된 관계입니다. 자료 추상화 추상화는 개발자가 객체의 구현 세부 사항에 신경 쓰지 않고도 객체의 기능에 집중할 수 있도록 해주는 중요한 개념입니다. 코드의 복잡성을 줄이고 가독성을 높이는 데 중요한 역할을 합니다. 데이터 추상화를 사용하면, 객체의 실제 구현 내용을 숨기고 사용자에게 필요한 기능만을 제공하는 인터페이스를 제공할 수 있습니다. 이를 통해, 객체의 내부 구현이 변경되더라도 사..
프로그래머라면 형식을 깔끔하게 맞춰 코드를 짜야 합니다. 코드 형식을 맞추기 위해 간단한 규칙을 정하고 그 규칙을 따라야 합니다. 필요하다면 규칙을 자동으로 적용하는 도구를 활용할 수 있습니다. 형식을 맞추는 목적 오늘 구현한 기능이 다음 버전에서 바뀔 확률은 매우 큽니다. 오늘 구현한 코드의 가독성은 앞으로 바뀔 코드의 품질에 지대한 영향을 미칩니다. 오랜 시간이 지나 원래 코드의 흔적을 찾기 어려울 정도로 코드가 바뀌어도 맨 처음 잡아놓은 구현 스타일과 가독성은 앞으로의 유지보수에 영향을 끼칩니다. 적절한 행 길이를 유지하라 자바에서 파일 크기는 클래스 크기와 밀접합니다. 위 사진은 각각 JUnit, FitNesse, testNG, TAM, JDepend, Ant, Tomcat 프로젝트를 조사한 결과..
잘 달린 주석은 무엇보다도 유용합니다. 그러나, 경솔하고 근거 없는 주석은 코드를 이해하기 어렵게 만듭니다. 오래되고 조잡한 주석은 거짓과 잘못된 정보를 퍼트립니다. 우리는 코드로 모든 의도를 표현하지 못해, 그러니 실패를 만회하기 위해 주석을 사용합니다. 주석은 언제나 실패를 의미합니다. 의도는 코드만으로 표현될수록 깨끗합니다. 코드는 변화하고 진화합니다. 일부가 여기서 저기로 옮겨지기도 하고, 조각이 나뉘고 갈라지고 합쳐지고를 반복합니다. 주석까지 함께 유지보수되는 경우는 정말 드물고, 언제나 따라가지 않습니다. 부정확한 주석은 아예 없는 주석보다 훨씬 나쁩니다. 부정확한 주석은 독자를 현혹시킵니다. 그러나 진실은 코드에 있습니다. 코드만이 자기가 하는 일을 진실되게 말합니다. 그러므로 우리는 주석을..
작게 만들어라 함수를 만드는 첫 번째 규칙은 ‘작게!’ 입니다. 함수를 만드는 둘째 구칙은 ‘더 작게!’ 입니다. 함수에서의 들여쓰기 수준은 1단이나 2단을 넘어서면 읽기 매우 힘들어집니다. 한 함수에 많은 중첩 구조가 들어가지 않도록 해야합니다. 한 가지만 해라 “함수는 한 가지를 해야 한다. 그 한가지를 잘 해야 한다. 그 한가지만을 해야 한다.” 우리가 함수를 만드는 이유는 큰 개념을 다음 추상화 수준에서 여러 단계로 나눠 수행하기 위함입니다. 함수 당 추상화 수준은 하나로 함수가 확실히 ‘한 가지’ 작업만 하려면 함수 내 모든 문장의 추상화 수준이 동일해야 합니다. 한 함수 내에 추상화 수준을 섞으면 코드를 읽는 사람이 헷갈립니다. 특정 표현이 근본 개념인지 세부사항인지 구분하기가 어려워집니다. ..
소프트웨어에서 이름은 어디나 쓰입니다. 우리는 변수, 함수, 인수, 클래스, 패키지, 파일과 폴더 등 모두 이름을 붙입니다. 이렇게 많이 쓰이는 이름을 처음에 한 번 잘지으면 앞으로의 개발이 편해집니다. 의도를 분명히 밝혀라 좋은 이름을 만드는데에는 시간이 걸릴 수 있으나, 그로인해 앞으로 절약될 시간은 더 큽니다. 개발을 하다가도, 더 나은 이름이 생각나면 모두 바꾸십시오. 변수나 함수, 클래스의 이름은 존재 이유 수행 기능 사용 방법 을 주석 없이 표현할 수 있어야 합니다. int d; // 경과 시간(단위: 날짜) 보다 int elapsedTimeInDays; int daysSinceCreation; 와 같이 의도가 드러나는 이름을 사용하면 코드 이해와 변경이 쉬워집니다. 그릇된 정보를 피하라 널리..
나쁜 코드를 치르는 대가 나쁜 코드는 개발 속도를 크게 떨어뜨린다. 매번 얽히고설킨 코드를 ‘해독’해서 얽히고설킨 코드를 더한다. 시간이 지나면서 쓰레기 더미는 점점 높아지고 깊어지고 커진다. 나쁜 코드가 쌓일수록 생산성을 떨어지고, 0에 가까워진다. 나쁜 코드는 엉망으로 유지시키고, 기한 내로 프로젝트를 완성하지 못하게 한다. 빨리 나아가는 유일한 방법은 코드를 최대한 깨끗하게 유지하는 습관이다. 깨끗한 코드란? 깨끗한 코드는 다른 사람들도 쉽게 읽을 수 있을 정도로 이해하고 수정하기 쉬우며, 버그가 적고 유지보수가 용이한 코드를 말한다. 책 속에는 소프트웨어 업계의 대부들이 생각하는 깨끗한 코드들에 대한 각자의 생각이 담겨있다. 우리는 코드를 짜는 시간보다 들여다보는 시간이 많다. 대부분은 코딩을 하..