반응형

IT Book/클린 코드(Clean Code) 15

[Clean Code] 15. Junit 들여다보기 - 클린 코드 정독하기

JUnit 프레임워크 JUnit은 자바 프레임워크 중에서 가장 유명하다. 개념은 단순하며 정의는 정밀하고 구현은 우아하다. JUnit은 저자가 많지만 시작은 켄트 벡과 에릭 감마, 두 사람이 비행기를 타고 가다 JUnit을 만들었다. 지금부터 살펴볼 예제는 문자열 비교 오류를 파악할 때 유용한 모듈이다. ComparisonCompactor는 두 문자열을 받아 차이를 반환한다. 예를 들어, ABCDE와 ABXDE를 받으면 를 반환한다. 다음은 ComparisonCompactor 모듈의 테스트 코드다. [15-1] ComparisonCompactorTest.java import junit.framework.ComparisonCompactor; import junit.framework.TestCase; pub..

[Clean Code] 14. 점진적인 개선 - 클린 코드 정독하기

프로그램을 짜다 보면 종종 명령행 인수의 구문을 분석할 필요가 생긴다. 편리한 유틸리티가 없다면 main 함수로 넘어오는 문자열 배열을 직접 분석하게 된다. 여러 가지 훌륭한 유틸리티가 있지만 내 사정에 딱 맞는 유틸리티가 없다면 직접 구현해야 한다. 간단한 예로 직접 구현할 유틸리티 Args를 작성해 보자 [14-1] Args 사용법 public static void main(String[] args) { try { Args arg = new Args("l,p#,d*", args); boolean logging = arg.getBoolean('l'); int port = arg.getInt('p'); String directory = arg.getString('d'); executeApplication..

[Clean Code] 13. 동시성 - 클린 코드 정독하기

객체는 처리의 추상화다. 스레드는 일정의 추상화다. - 제임스 O. 코플리엔(James O. Coplien) - 동시성과 깔끔한 코드는 양립하기 어렵다. 스레드를 하나만 실행하는 코드는 짜기 쉽다. 겉으로 보기에는 멀쩡하나 깊숙한 곳에 문제가 있는 다중 스레드 코드도 짜기 쉽다. 이런 코드는 시스템이 부하를 받기 전까지 멀쩡하게 돌아간다. 동시성이 필요한 이유? 동시성은 결합(Coupling)을 없애는 전략이다. 즉, 무엇(What)과 언제(When)를 분리하는 전략이다. 스레드가 하나인 프로그램은 무엇과 언제가 서로 밀접하다. 흔히 단일 스레드 프로그램을 디버깅하는 개발자는 breakpoint를 정한 후 어느 지점에 걸렸는지 살펴보면서 시스템 상태를 파악한다. 무엇과 언제를 분리하면 애플리케이션 구조와..

[Clean Code] 12. 창발성 - 클린 코드 정독하기

창발적 설계로 깔끔한 코드를 구현하자 켄트 벡이 제시한 네 가지 단순한 설계 규칙 모든 테스트를 실행한다. 중복을 없앤다. 프로그래머 의도를 표현한다. 클래스와 메서드 수를 최소로 줄인다. 켄트 벡이 제시한 규칙을 따르면 설계는 단순하다. 코드 구조와 설계를 파악하기 쉬워지고 단일 책임 원칙(SRP), 의존 관계 역전 원칙(DIP)과 같은 원칙을 적용하기 쉬워진다. 위 네 가지 규칙이 우수한 설계의 창발성을 촉진한다. 단순한 설계 규칙 1: 모든 테스트를 실행하라 문서로는 시스템을 완벽하게 설계했지만, 시스템이 의도한 대로 돌아가는지 검증할 방법이 없다면, 문서 작성을 위해 투자한 노력에 대한 가치는 인정받기 힘들다. 테스트를 철저하게 거쳐 모든 테스트 케이스를 항상 통과하는 시스템은 ‘테스트가 가능한 ..

[Clean Code] 11. 시스템 - 클린 코드 정독하기

“복잡성은 죽음이다. 개발자에게서 생기를 앗아가며, 제품을 계획하고 제작하고 테스트하기 어렵게 만든다.” 레이 오지(Ray Ozzie) 도시를 세운다면? 도시를 세운다면 온갖 세세한 사항을 혼자서 직접 관리할 수는 없다. 이미 세워진 도시라도 한 사람의 힘으로는 무리다. 그럼에도 불구하고 도시는 돌아간다. 도시가 돌아가는 이유에는 수도 관리, 전력 관리, 교통 관리 등 각 분야를 관리하는 팀이 있기 때문이다. 도시에는 큰 그림을 그리는 사람들도 있으며 작은 사항에 집중하는 사람들도 있다. 도시가 돌아가는 또 다른 이유는 적절한 추상화와 모듈화 때문이다. 그래서 큰 그림을 이해하지 못하더라도 개인과 개인이 관리하는 ‘구성요소’는 효율적으로 돌아간다. 소프트웨어 팀도 도시처럼 구성한다. 그런데 막상 팀이 제..

[Clean Code] 10. 클래스 - 클린 코드 정독하기

코드, 코드 블록, 함수 구현, 함수가 서로 관련 맺는 방식 등 코드의 표현력과 그 코드로 이루어진 함수에 아무리 신경 쓸지라도 좀 더 차원 높은 단계까지 신경 쓰지 않으면 깨끗한 코드를 얻기는 어렵다. 이 장에서는 깨끗한 클래스를 다룬다. 클래스 체계 클래스를 정의하는 표준 자바 관례에 따르면, 가장 먼저 변수 목록이 나온다. 변수는 static public 상수가 있다면 맨 처음에 나온다. 다음으로 static private 변수가 나오며, 이어서 private 인스턴스 변수가 나온다. 공개 변수가 필요한 경우는 거의 없다. 변수 목록 다음에는 public 함수가 나온다. private 함수는 자신을 호출하는 public 함수 직후에 넣는다. 즉, 추상화 단계가 순차적으로 내려간다. 캡슐화 변수와 유..

[Clean Code] 9. 단위 테스트 - 클린 코드 정독하기

TDD 법칙 세 가지 실패하는 단위 테스트를 작성할 때까지 실제 코드를 작성하지 않는다. 컴파일은 실패하지 않으면서 실행이 실패하는 정도로만 단위 테스트를 작성한다. 현재 실패하는 테스트를 통과할 정도로만 실제 코드를 작성한다. 위 세 규칙을 따르면 테스트 코드와 실제 코드가 함께 나올 뿐만 아니라 매일 수십 개에 달하는 테스트 케이스가 나온다. 실제 코드를 사실상 전부 테스트하는 테스트 케이스가 나온다. 하지만 실제 코드와 맞먹을 정도로 방대한 테스트 코드는 심각한 관리 문제를 유발하기도 한다. 깨끗한 테스트 코드 유지하기 지저분한 테스트 코드는 테스트를 안 하는 것보다 못하다. 실제 코드가 진화하면 테스트 코드도 변해야 한다. 테스트 코드가 지저분할수록 변경하기 어려워진다. 테스트 코드가 복잡할수록 ..

[Clean Code] 8. 경계 - 클린 코드 정독하기

시스템에 들어가는 모든 소프트웨어를 직접 개발하는 경우는 드물다. 때로는 패키지를 사고, 때로는 오픈 소스를 이용한다. 때로는 사내 다른 팀이 제공하는 컴포넌트를 사용한다. 어떤 식이로든 외부 코드를 우리 코드에 깔끔하게 통합해야만 한다. 외부 코드 사용하기 패키지 제공자나 프레임워크 제공자는 더 많은 환경에서 돌아가도록 하기 위해 적용성을 최대한 넓히려 하는 반면에, 사용자는 자신의 요구에 집중하는 인터페이스를 바란다. 이로 인해 시스템 경계에서 문제가 생길 소지가 많다. 자바의 java.util.Map은 굉장히 다양한 인터페이스로 수많은 기능을 제공한다. Map이 제공하는 기능성과 유연성은 확실히 유용하지만 그만큼 위험도 크다. 예를 들어 프로그램에서 Map을 만들어 여기저기 넘긴다고 가정하자. Ma..

[Clean Code] 7. 오류 처리 - 클린 코드 정독하기

오류 코드보다 예외를 사용하라 얼마 전까지만 해도 예외를 지원하지 않는 프로그래밍 언어가 많았다. 예외를 지원하지 않는 언어는 오류를 처리하고 보고하는 방법이 제한적이었다. public class DeviceController { ... public void sendShutDown() { DeviceHandle handle = getHandle(DEV1); // 디바이스 상태를 점검한다. if (handle != DeviceHandle.INVALID) { // 레코드 필드에 디바이스 상태를 저장한다. retrieveDeviceRecord(handle); // 디바이스가 일시정지 상태가 아니라면 종료한다. if (record.getStatus() != DEVICE_SUSPENDED) { pauseDevic..

[Clean Code] 6. 객체와 자료구조 - 클린 코드 정독하기

변수를 private로 정의하는 이유는 남들이 변수에 의존하지 않게 만들고 싶어서다. 충동이든 변덕이든, 변수 타입이나 구현을 마음대로 바꾸고 싶어서다. 그렇다면 왜 get 함수(getter)와 set 함수(setter)를 당연하게 공개(public)해 비공개 변수를 외부에 노출할까? 자료 추상화 다음 두 클래스는 2차원 점을 표현한다. 그런데 한 클래스는 구현을 외부로 노출하고 다른 클래스는 구현을 완전히 숨긴다. // 구체적인 Point 클래스 public class Point { public double x; public double y; } // 추상적인 Point 클래스 public interface Point { double getX(); double getY(); void setCartesi..

반응형