자바/클린 코드 16

클린코드 17장 - 냄새와 휴리스틱

마틴파울러의 리팩토링 책에서도 언급하는 것처럼, 우리가 소스를 보다보면 리팩토링이 필요한 나쁜 냄새나는 부분들을 찾을 수 있다. 주석 C1. 부적절한 정보 : 변경이력, 작성자, 최종수정일 등은 다른시스템(소스관리, 버그추적, 이슈추적 등)에 저장할 정보이다. 주석은 코드와 설계에 기술적인 설명을 부연하는 수단이다. C2. 쓸모 없는 주석 : 오래되거나 엉뚱하고 잘못된 주석은 더이상 쓸모다 없다. 코드와 무관하게 혼자서 따로 놀며 코드를 그릇된 방향으로 이끈다. C3. 중복된 주석 : 코드에 이미 있는 내용을 구구절절 반복할 필요는 없다. /** * @param sellRequest * @return * @throws ManagedComponentException */ public SellResponse..

클린코드 14장 - 점진적인 개선

리팩토링은 루빅 큐브 맞추기와 비슷하다. 리팩토링을 하다 보면 코드를 넣었다 뺐다 하는 사례가 아주 흔하다. 좀전에 넣은 예외코드를 다른 로직을 수정하면서 바로 빼 버리기도 한다. 큰 목표 하나를 이루기 위해 자잘한 단계를 수없이 거친다. 각 단계를 거쳐야 다음 단계가 가능하다. https://github.com/seaking7/cleancode-args GitHub - seaking7/cleancode-args Contribute to seaking7/cleancode-args development by creating an account on GitHub. github.com 결론 단순히 돌아가는 코드에 만족하는 프로그래머는 전문가 정신이 부족하다. 나쁜 코드보다 더 오랫동안 더심각하게 개발 프로젝트..

클린코드 13장 - 동시성

동시성과 깔끔한 코드는 양립하기 어렵다. 이런 어려움을 대처하고 깨끗한 코드를 작성하는 방법을 알아보자. 동시성이 필요한 이유? 쓰레드가 하나인 프로그램은 무엇과 언제가 서로 밀접하다. 동시성은 무엇과 언제를 분리하는 전략이다. 웹애플리케이션에서 서블릿 모델을 보면, 웹 요청이 올때마다 각 서블릿 스레드가 각각 자신만의 세상에서 돌아감에 따라 많은 구조적 이점을 가진다. 또한, 많은 배치프로그램에서 하나의 쓰레드가 수행할 때보다 많은 일을 동시성을 이용해서 해결하고 있다. 하지만, 동시성은 각별히 주의하지 않으면 난감한 상황에 처하게 되며, 동시성과 관련된 일반적인 미신과 오해가 있다. 1) 동시성은 항상 성능을 높여준다 : 동시성은 때로 성능을 높여준다. 대기시간이 길거나, 독립적인 계산이 충분히 많은..

클린코드 12장 - 창발성

창발성 : 불시에 솟아나는 특성 창발적 설계로 깔끔한 코드를 구현하자. 우수한 설계를 유지하는 단순한 설계 규칙은 아래 네가지로 요약된다. 1. 모든 테스트를 실행하라 테스트가 가능한 시스템을 만들려고 하면, 크기가 작고 목적 하나만 수행하는(SRP) 클래스가 나온다. 결합도가 높으면 테스트 코드를 작성하기 어려워지므로, 테스트 코드를 만들려면 DIP와 같은 원칙을 적용하고, 의존성주입, 인터페이스, 추상화와 같은 도구를 통해 결합도를 낮추게 된다. 테스트 케이스를 만들고 계속 돌리려고 하면 시스템은 낮은 결합도와 높은 응집력을 유지할 수 밖에 없다. 2. 중복을 없애라. 중복은 추가 작업, 추가 위험, 불필요한 복잡도를 뜻한다. 비슷한 코드는 더 비슷하게 고쳐서 별도 메서드 등으로 빼내라. 비슷한 업무..

클린코드 11장 - 시스템

도시를 설계할때에도 수도관리팀, 전력관리팀, 교통관리팀, 치안관리팀, 건축물관리팀 등 각 분야의 담당자들이 적절한 추상화와 모듈화로 일을 하기 때문에 잘 돌아갈 수 있다. 소프트웨어도 추상화와 관심사 분리를 통해 깨끗한 시스템을 유지해야 한다. 생성(Configuration) 과 사용(애플리케이션, Service) 분리 아래와 같이 서비스 사용부에서 생성까지 책임지는 소스는 아래와 같은 문제가 있다. 1. getService()에서 MyServiceImpl이라는 구체적인 객체에 의존한다. 2. 단위테스트 구현시 MyServiceImpl이 복잡한 로직이라면, Test Double 을 service에 할당해야 하는데 불가능하다. 3. service가 null일 경우와 아닐 경우 등 객체 생성에 대한 테스트도..

클린코드 10장 - 클래스

클래스 체계 클래스는 public static 변수 → private static 변수 → private 변수 순으로 배치. public 변수가 필요한 경우는 거의 없다. 변수 목록 다음에는 public 함수를 배치하며, private 함수는 자신을 호출하는 함수 직후에 넣는다. 즉, 추상화 단계가 순차적으로 내려가서, 신문 기사처럼 읽혀야 한다. 캡슐화 테스트 코드에서 private 변수나 함수에 접근하려고 하면 protected로 선언하는 방법도 있으나, 테스트 코드에서 private 변수나 함수에 접근해야 하는 경우는 별도 클래스로 빼는게 맞다. 클래스는 작아야 한다. 하나의 함수가 하나의 행동만을 해야 했다면, 하나의 클래스는 하나의 책임만을 맡아야 한다. 간결한 클래스 이름이 떠오르지 않는다면 ..

클린코드 9장 - 단위테스트

애자일과 TDD덕택에 단위테스트를 자동화하는 프로그래머들이 많아졌으며 점점 늘어나는 추세다. 하지만, 테스트를 추가하려고 급하게 서두르는 와중에 제대로 된 테스트 케이스를 작성해야 한다는 더 중요하고 미묘한 사실을 놓치고 있다. TDD법칙 세 가지 첫째 법칙 : 실패하는 단위 테스트를 작성할 때까지 실제 코드를 작성하지 않는다. 둘째 법칙 : 컴파일은 실패하지 않으면서 실행이 실패하는 정도로만 단위 테스트를 작성한다. 셋째 법칙 : 현재 실패하는 테스트를 통과할 정도로만 실제 코드를 작성한다. 실패하는 테스트 추가 → 최소한의 코딩을 통한 테스트 통과 → 테스트 통과를 유지하면서 구조/설계 개선 깨끗한 테스트 코드 유지하기 테스트 코드는 구현에 신경쓰지 않고 조금 지저분해도 빨리 개발하는게 좋다고 생각하..

클린코드 8장 - 경계

외부 코드 사용하기 외부 코드(다른 팀의 컴포넌트 또는 오픈소스)는 기능성과 유연성을 제공하기 위해 필요이상의 기능을 제공할 수가 있다. 아래와 같이 Sensor를 담는 Map(외부 인터페이스)을 사용하면, get할때마다 캐스팅을 해야 한다. Map sensors = new HashMap(); ... Sensor s = (Sensor)sensors.get(sensorId); 아래와 같이 Generics를 사용하면 조금 나아지지만, Map인터페이스가 변하면 소스를 다 수정해야 한다. Map sensors = new HashMap(); ... Sensor s = sensors.get(sensorId); 아래와 같이 Map을 Sensors 안으로 숨기면, Map이 변해도 나머지 프로그램에 영향을 미치지 않는다..

클린코드 7장 - 오류처리

오류 코드보다 예외를 사용하라 오류를 코드로 관리하면, 함수를 호출하는 호출자 코드가 복잡해진다. 예외를 던지면, 실제 로직과 오류처리 로직이 뒤섞이지 않으니까 호출자 코드가 더 깔끔해진다. // Bad public class DeviceController { ... public void sendShutDown() { DeviceHandle handle = getHandle(DEV1); // Check the state of the device if (handle != DeviceHandle.INVALID) { // Save the device status to the record field retrieveDeviceRecord(handle); // If not suspended, shut down if..

클린코드 6장 - 객체와 자료구조

6장에서는 자료구조와 객체의 두가지 개념을 소개한다. 자료구조는 자료를 그대로 공개하며 별다른 함수를 제공하지 않는게 좋다. VO나 DTO 객체를 의미한다. 객체는 추상화 뒤로 자료를 숨긴 채 자료를 다루는 함수만 공개한다. 자료구조 형식의 클래스 public class Point { public double x; public double y; } 추상적인 객체 방식의 클래스 public interface Point { double getX(); double getY(); void setCartesian(double x, double y); double getR(); double getTheta(); void setPolar(double r, double theta); } (자료구조를 사용하는) 절차적인..

반응형