POST 요청은 일반적으로 데이터를 body로 보낸다 @PostMapping(value = "/boards/{boardId}", params = "command=move") public ResponseEntity movePiece(@PathVariable int boardId, @RequestBody CommendDto commendDto) { gameService.move(boardId, commendDto); return ResponseEntity.ok(gameService.gameStateAndPieces(boardId)); } 처음에 위와 같이 코드를 짰었다. boardId에 해당하는 체스판을 CommandDto 안의 위치 정보를 통해 체스 말을 움직이는 요청을 처리한다. 그런데 위와 같은 피드백..
자바
공식 문서에 의하면 스프링 웹 MVC는 서블릿 API 기반의 웹 프레임워크이다. 스프링 MVC에 대해 공부하던 중 서블릿에 대한 개념을 간단히 집고 넘어가야 진행할 수 있을 것 같아 정리해 보았다. 서블릿이란? 서블릿은 웹 서버 내에서 실행되는 작은 자바 프로그램(인터페이스)이다. 일반적으로 HTTP를 통해 웹 클라이언트의 요청을 수신하고 응답하며 동적 웹 페이지를 만들 때 사용된다. 개발자가 HTTP 요청과 응답을 직접 다 파싱하고 응답을 만든다고 생각하면 해야 할 일이 너무 많다. 하지만 서블릿을 사용한다면 개발자는 HTTP 스펙을 매우 편리하게 사용할 수 있다. Servlet 인터페이스는 서블릿을 초기화하고, 요청을 처리하고, 서버에서 서블릿을 제거하는 방벙을 정의한다. 아래는 HttpServlet..
IllegalArgumentException vs IllegalStateException @Override public State proceed(Command command) { if (command.isMove()) { throw new IllegalArgumentException(CANNOT_MOVE); } if (command.isStatus()) { throw new IllegalStateException(CANNOT_GENERATE_SCORE); } // ... } IllegalArgumentException과 IllegalStateException을 혼용하여 사용하고 있었고 리뷰어가 이를 지적했다. 각 기능을 만들 때 이 두 예외를 언제 써야 하는지 정확한 기준을 잡지 못했던 것이다. 다음 글..
테스트 더블 테스트 더블이란 실제 프로덕션 코드에서 쓰이지 않는 객체를 사용해 테스트를 진행하는 것을 의미한다. 애플리케이션을 개발할 때 테스트 코드도 프로덕션 코드 못지않게 중요하다. 그 중요한 테스트 코드를 왜 실제 객체가 아닌 다른 객체로 테스트를 하는 것일까? 다른 이유도 있겠지만 다음의 두 가지 이유가 중요하다고 생각한다. 1. 테스트 하려는 객체와 연관된 객체가 사용하기 어려운 경우 2. 테스트 하려는 객체와 연관된 객체의 상태에 상관없이 테스트하고자 하는 객체만 테스트하고 싶은 경우 어찌보면 비슷한 말이다. 즉 연관된 객체와 테스트하고자 하는 객체를 분리하고 싶은 것이다. 연관된 객체에 문제가 생기더라도 테스트하고자 하는 객체의 테스트는 통과할 수 있어야 옳게 된 단위 테스트이다. (물론 연..
IllegalArgumentException 가장 많이 사용되는 예외 중 하나로 호출자가 인수로 부적절한 값을 넘길 때 던지는 예외이다. 예를 들어 정수 파라미터를 받고 양수만 들어와야 한다고 할 때 음수가 들어오면 사용할 수 있다. public void onlyPlus(int number) { if (number
최상단 directory 하위에 docker directory를 생성 하위에 docker-compose.yml 파일 생성 version: "3.9" services: db: image: mysql:8.0.28 platform: linux/x86_64 restart: always ports: - "3306:3306" environment: MYSQL_ROOT_PASSWORD: root MYSQL_DATABASE: practice MYSQL_USER: user MYSQL_PASSWORD: password TZ: Asia/Seoul volumes: - ./db/mysql/data:/var/lib/mysql - ./db/mysql/config:/etc/mysql/conf.d - ./db/mysql/init:/d..
열거 타입의 확장은 불가능? 열거 타입은 활용하기 좋지만 확장할 수 없다는 단점이 있다. 쉽게 말해서 Enum 타입은 상속이 불가능하다. 사실 대부분의 상황에서 열거 타입을 확장하는 것은 좋지 않은 생각이다. 열거 타입은 원소들을 순회할 수 있는데 기반 타입과 확장 타입을 모두 순회하는 방법도 마땅치 않다. 열거 타입은 인터페이스를 구현할 수 있다. 열거 타입을 상속받는 것은 불가능하다. 하지만 열거 타입이 인터페이스를 구현하는 것은 가능하다. 상위 인터페이스를 정의하고 이를 확장한 여러 열거 타입으로 유연하게 여러 열거 타입 구현체를 사용할 수 있다. 아래는 체스 미션에서 사용한 인터페이스와 열거 타입을 사용한 예시이다. 체스 미션에서 활용한 방향 열거 타입 체스 기물인 킹, 퀸, 폰, 룩, 비숍, 나..
11.1 값이 없는 상황을 어떻게 처리할까 클래스 내부에 필드로 객체를 가지는 상황에서 객체가 비어 있고, 해당 필드에 접근하려 하면 NullPointerException이 발생한다. 보수적인 자세로 if (객체 == null)을 많이 사용하여 null을 피해 갈 수도 있을 것이다. 변수를 접근할 때마다 if가 늘어나고 코드 들여 쓰기가 늘어난다. 이와 같은 반복 패턴 코드를 ‘깊은 의심’이라고 한다. null 때문에 발생하는 문제 에러의 근원이다: NullPointerException은 가장 흔한 에러 코드를 어지럽힌다: null 확인 코드를 추가해야 하므로 아무 의미가 없다: null은 아무 의미도 표현하지 않는다. 자바 철학에 위배된다: 자바는 개발자로부터 모든 포인터를 숨겼지만 null은 예외 형..