본문 바로가기

Clean Code

(12)
동시성을 구현할 때 명심할 것들 #12 목차 1. 동시성 프로그래밍이란 2. 동시성 프로그래밍이 필요한 이유 3. 안전한 동시성 프로그래밍 규칙 4. 동시성 테스트 방법 동시성 프로그래밍이란? 어플리케이션을 효율적으로 실행하기 위해 멀티코어를 온전히 활용하도록 구현하는 방식 동시성 프로그래밍이 필요한 이유 동시성 프로그래밍의 미신과 오해(1) 동시성은 항상 성능을 높여준다 (X) 동시성은 때로 성능을 높여준다 (0) 대시 시간이 아주 길어 여러 스레드가 프로세서를 공유할 수 있거나, 여러 프로세서가 동시에 처리할 독립적인 계산이 충분히 많은 경우에만 성능이 높아진다. 예시 : 웹 브라우저에서 여러 이미지 리소스들을 불러와 다운로드할 때 예시 상황 : Servlet Java Servlet 동시성 구현 요청이 들어오면 Thread Pool에 있는..
창발적 설계로 깔끔한 코드 구현하기 #11 1. 창발성 2. 창발적 설계 2. 모든 테스트를 실행한다. 3. 중복을 없앤다. 4. 의도를 표현한다. 5. 실용적 관점에서 타협한다. 창발성 하위 계층에는 없는 특성이나 행동이 상위 계층(전체 구조)에서 자발적으로 돌연히 출연하는 현상. 각각의 개미는 집을 지을 능력이 없지만, 작은 개미들의 상호작용을 통해 집이라는 결과물이 나오는 것처럼, 작은 요소들의 상호작용의 반복이 전체 구조에 영향을 미친다. 창발적 설계 단순한 4가지를 반복하다 보면 전체적으로 깨끗한 코드가 만들어진다. 1. 모든 테스트를 실행한다. 2. 중복을 없앤다. 3. 프로그래머 의도를 표현한다. 4. 클래스와 메서드 수를 최소로 줄인다. 실용적 관점에서 타협한다. - 켄드 백 모든 테스트를 실행한다. 모든 테스트 케이스를 항상 통과..
관심사 분리 패턴 #10 관심사 분리 소프트웨어는 (애플리케이션 객체를 제작하고 의존성을 서로 '연결'하는) 준비과정과 (준비 과정에 이어지는) 런타임 로직을 분리해야 한다. 객체의 생성과 객체를 사용하는 부분을 분리한다. 시작에 대한 관심사 분리 시작 단계는 모든 애플리케이션이 풀어야 할 관심사다. main 함수에서 시스템에 필요한 객체를 생성한 후 애플리케이션에 넘긴다. 애플리케이션은 그저 만들어진 객체를 사용한다. 모든 객체가 생성되었다고 가정하고, 객체를 이용한 개발에 집중할 수 있다. 요청에 대한 관심사 분리 Spring 프레임워크를 통해 요청에 대한 관심사를 분리해 요청 처리에 대한 비즈니스 로직에 집중할 수 있다. Servlet Filter 서블릿 필터는 DispatcherServlet 이전에 실행이 되는데 요청 내..
클래스를 잘 설계하기 #9 목차 캡슐화되어야 한다. 단일 책임 원칙 낮은 결합도, 높은 응집도 변경하기 쉬워야 한다. 캡슐화되어야 한다. 객체의 실제 구현을 오부로부터 감추는 방식 클래스를 개발할 때 기본적으로 구현을 감추고, 외부 객체와 상호작용하는 부분만 노출한다. 외부의 잘못된 사용을 방지한다. 경계에서 배웠던 부분! Map Stack 예제 필드를 private로 제한, get 으로 읽기 수정은 push, pop 메서드를 통해서 일어나도록 제한 class Stack { class Node { private T data; private Node prev; Node(T data) { this.data = data; } } private Node top; public void push(T data) { Node node = new..
단위 테스트 #8 목차 테스트 코드의 중요성 테스트의 종류 Unit Test 작성 테스트 코드의 중요성 테스트 코드는 실수를 바로 잡아준다. 테스트 코드는 반드시 존재해야하며, 실제 코드 못지 않게 중요하다. 테스트 케이스는 변경이 쉽도록 한다. 코드에 유선성, 유지보수성, 재사용성을 제공하는 버팀목이 바로 단위테스트다. 테스트 케이스가 있으면 변경이 두렵지 않다. 테스트 케이스가 없다면 모든 변경이 잠정적인 버그다. 테스트 커버리지가 높을수록 버그에 대한 공포가 줄어든다. 지저분한 테스트 코드는 테스트를 안하니만 못하다. 테스트는 자동화되어야 한다. 테스트를 양심껏 가끔하는 것이 아니라 매번 배포하기전에 테스트를 실행하여 잘 동작하는지 검증하여야 한다. 테스트 의 종류 Test Pyramid Unit Test : 프로그..
모호한 경계를 구분짓기 #7 목차 경계 경계 짓기 (1) 우리 코드를 보호하기 경계 짓기 (2) 외부 코드와 호환하기 외부 라이브러리 테스트하기 - Learning Test 경계 오픈소스, 라이브러리를 안쓰는 프로젝트는 없다. 우리가 만든 코드에 외부에서 들어온 코드를 병합해야 한다. 외부 코드는 외부에서 만든 코드인데, 외부 시스템과 호출하거나 단순히 외부에서 만들어진 코드일 수 있다. 우리 코드와 외부코드를 깔끔하게 통합시키기 위해 경계를 잘 지어야 한다. 경계 짓기(1) 우리 코드를 보호하기 캡슐화(Encapsulation) 객체의 실제 구현을 외부로부터 감추는 방식 우리 코드를 보호하기 Sensor 를 관리하고 싶다. Sensor는 외부에서 사용된다. Sensor id와 Sensor 객체로 저장하고 싶어서, Map을 사용한다..
예외 처리하기 #6 목차 예외 처리 방식 Unchecked Exception을 사용하라 Exception 잘 쓰기 실무 예외 처리 패턴 오픈소스 속 Exception 살펴보기 예외 처리 방식 오류 코드를 리턴하지 말고, 예외를 던져라 옛날에는 오류를 나타낼 때 에러코드를 던졌다. 하지만 예외를 던지는 것이 명확하고, 처리 흐름이 깔끔해진다. 오류가 발생한 부분에서 예외를 던진다. (별도의 처리가 필요한 예외라면 checked exception으로 던진다) checked exception에 대한 예외처리를 하지 않는다면 메서드 선언부에 throws를 명시해야 한다. 예외를 처리할 수 있는 곳에서 catch 하여 처리한다. Unchecked Exception을 사용하라 Checked vs Unchecked Exception E..
객체와 자료구조 #5 목차 자료구조 vs 객체 객체 - 디미터 법칙 DTO Active Record 자료구조 vs 객체 자료구조 객체 데이터 그 자체 비즈니스 로직과 관련 자료를 공개한다. 자료를 숨기고, 추상화 한다. 자료를 다루는 함수만 공개한다. 변수 사이에 조회 함수와 설정 함수로 변수를 다룬다고 객체가 되지 않는다. 추상 인터페이스를 제공해 사용자가 구현을 모른채 자료의 핵심을 조작할 수 있다. 예시 1 //자료구조 public interface Vehicle { double getFuelTankCapacityInGallons(); // 연료탱크 용량(갤런 단위) double getGallonsOfGasoline(); // 가솔린 (갤런 단위) } public class Car implements Vehicle { ..