본문 바로가기

우아한테크코스/공부14

테스트 코드에 대한 나의 생각 모락 프로젝트를 진행하면서 제일 많이 고민했던 것은 테스트 코드이다. 따라서 테스트 코드에 대해서 내가 느낀 생각들에 대해서 정리해보려고 한다. 테스트 코드는 왜 작성해야 할까? 프로젝트를 하면서 제일 크게 느낀 것은 테스트 코드는 서비스의 품질을 보장한다. 테스트 코드를 이용하여 서비스에서 발생할 수 있는 에러를 미리 방지할 수 있다. 일단 우테코를 진행하면서, 테스트 코드를 작성하지 않는 것을 생각해본 적이 없다. 테스트 코드는 서비스에 생기는 에러를 미리 확인할 수 있게 해 준다. 테스트 코드가 작성되지 않은 서비스가 존재한다고 가정한다면, 개발자는 서비스를 배포하고나서야 서비스에 생기는 에러를 직면할 수 있다. 이러한 상황을 피하고자 우리는 테스트 코드를 작성해야 한다. 그렇다면 테스트 코드는 얼.. 2022. 8. 16.
스프링 MVC 구조 파악하기 스프링 MVC의 핵심 구성 요소 간단 요약 1. DispatcherServlet은 모든 연결을 담당한다. 2. DispatcherServlet은 요청이 들어오면 요청을 처리하기 위한 컨트롤러를 찾기 위해 HandlerMapping 빈에게 검색을 요청한다. HandlerMapping빈은 요청을 처리할 컨트롤러 빈 객체를 DispatcherServlet에 전달한다. 3. DispatcherServlet은 HandlerAdapter 빈에게 컨트롤러 요청 처리를 위임한다. 4-6. HandlerAdapter빈은 컨트롤러를 통해 요청을 처리하고 ModelAndView라는 객체로 변환해서 DispatcherServlet에게 리턴한다. 7. DispatcherServlet은 ModelAndView 객체안의 view .. 2022. 6. 1.
빈 스코프 - prototype 스프링5 책 내용 간단 정리 스프링 컨테이너는 초기화와 종료라는 라이프 사이클을 가진다. 그리고 빈 객체의 라이프 사이클을 관리한다. 스프링 컨테이너의 라이프 사이클: 빈 객체 생성 -> 의존 설정 -> 빈 객체 초기화 (지정된 메서드 호출) -> 컨테이너 종료 시 빈 객체 소멸 처리 (지정된 메서드 호출) 빈 객체의 라이프 사이클 : 객체 생성 -> 의존 설정 -> 초기화 -> 소멸 빈 객체의 관리 범위 1. 싱글톤 (default) : 스프링 컨테이너의 시작과 종료까지 유지되는 가장 넓은 범위의 스코프 싱글 스코프의 빈을 조회하면 스프링 컨테이너에서 항상 같은 인스턴스의 스프링 빈을 반환한다. 2. 프로토 타입 : 빈 객체를 구할 때 마다 새로운 객체 생성한다. 싱글톤일 때 @Configuration.. 2022. 5. 26.
적시에 방어적 복사본을 만들라 적시에 방어적 복사본을 만들라 자바는 안전한 언어다. 그러나 클라이언트가 불변식을 깨뜨리려 한다고 가정하고 방어적 프로그래밍을 해야 한다. 방어적 프로그래밍을 해야 하는 예: public class Period { private final Date start; private final Date end; public Period(Date start, Date end) { if (start.compareTo(end) > 0) { throw new IllegalArgumentException(); } this.start = start; this.end = end; } } 위의 클래스는 불변처럼 보인다. 하지만 Date가 가변이므로 어렵지 않게 불변식을 깨뜨릴 수 있다. public static void mai.. 2022. 4. 4.
제네릭과 가변인수를 함께 쓸 때는 신중하라 가변인수와 제네릭은 자바 5때 함께 추가되었다. 이 둘은 궁합이 좋지 않다. 가변인수 기능은 배열을 노출하여 추상화가 완벽하지 못하다. 그리고 배열과 제네릭은 타입 규칙이 서로 다르다. 이 두 부분에서 궁합이 맞지 않는다. 가변인수 동작 방식 가변인수 메서드를 호출하면 가변인수를 담기위한 배열이 생성된다. 그런데 내부로 감춰야 했을 이 배열을 클라이언트에 노출하는 문제가 있다. 제네릭과 같은 실체화 불가 타입 런타임에서 컴파일보다 타입 관련 정보를 적게 담고 있다. 따라서 메서드 선언 시 가변인수 매개변수로 제네릭을 선언한다면 컴파일러가 경고를 보낸다. 제네릭과 varargs를 혼용하면 타입 안정성이 깨진다! static void dangerous(List... stringLists) { List int.. 2022. 4. 1.
태그 달린 클래스보다는 클래스 계층구조를 활용하라 태그 달린 클래스보다는 클래스 계층구조를 활용하라 다음 코드는 원과 사각형을 나타내는 코드다. public class Figure { enum Shape {RECTANGLE, CIRCLE} //태그 필드 - 현재 모양을 나타낸다. private Shape shape; // 사각형일 때 사용되는 필드 private double length; private double width; // 원일 때 사용되는 필드 private double radius; //원용 생성자 public Figure(double radius) { shape = Shape.CIRCLE; this.radius = radius; } //사각형용 생성자 public Figure(double length, double width) { shap.. 2022. 3. 29.
finalizer와 cleaner 사용을 피하라 finalizer와 cleaner 사용을 피하라 자바의 객체 소멸자 1. finalizer (자바 8까지) 예측 불가능하고, 상황에 따라 위험할 수도 있어 일반적으로 불필요 2. cleaner (자바 9~) finalizer보다는 덜 위험하지만 마찬가지로 예측 불가능, 느림, 일반적으로 불필요하다. 어째서 불필요한지? 1. finalizer와 cleaner는 즉시 수행된다는 보장이 없다. 즉, 두 가지로는 제때 실행되어야 하는 작업은 절대할 수 없다. ex) 파일 닫기의 경우, 동시에 열 수 있는 파일 개수에 한계가 있기 때문에, finalizer나 cleaner가 제 때 실행되지 않는다면, 새로운 파일을 열지 못하게 될 수 있다. 2. 수행 여부를 보장하지 않는다. 접근할 수 없는 일부 객체에 딸린 종.. 2022. 3. 22.
상속을 고려해 설계하고 문서화하라. 그러지 않았다면 상속을 금지하라 상속을 고려해 설계하고 문서화하라. 그러지 않았다면 상속을 금지하라 상속용 클래스는 재정의할 수 있는 메서드들을 내부적으로 어떻게 이용하는지 문서로 남겨야 한다. 재정의 가능 메서드를 호출할 수 있는 모든 상황을 문서로 남겨야한다. 메서드 설명을 작성하기위해 @implSpec 태그를 붙여주면 자바독 도구가 생성해준다. 다음은 java.util.AbstractCollection에서 찾은 예 위와 같이 메서드 설명을 통해서 내부 동작 방식을 알 수 있다. 이렇게 작성하는 것은 상속이 캡슐화를 해치기 때문이다. 클래스를 안전하게 상속할 수 있도록 하려면 내부 구현 방식을 설명해야만 한다. 문서를 남기는 것 뿐만 아니라 상속을 위해 훅(hook)을 잘 선별하여 protected 메서드 형태로 공개해야 할 수도 .. 2022. 3. 15.
스트림 병렬화는 주의해서 적용하라 자바 8부터 parallel 메서드만 한 번 호출하면 파이프라인을 병렬 실행할 수 있는 스트림을 지원한다. 이 병렬 실행을 올바르게 사용하는 방법을 알아보자. import static java.math.BigInteger.ONE; import static java.math.BigInteger.TWO; import java.math.BigInteger; import java.util.stream.Stream; // 스트림을 사용해 처음 20개의 메르센 소수를 생성하는 프로그램 public class Main { public static void main(String[] args) { primes().map(p -> TWO.pow(p.intValueExact()).subtract(ONE)) .filter(m.. 2022. 3. 12.