728x90

java 15

[썬카/백엔드] 커스텀 쿼리를 이용한 판매 차량 삭제 기능 구현 - Soft Delete 방식의 간접 CASCADE

일반적인 Hard Delete 방식을 사용했다면 외래키 관계를 이용한 엔티티와 DB 레벨에서의 cascade를 이용할 수 있었을 테지만, 중고차 거래 플랫폼 특성상 데이터의 신뢰도가 중요했기 때문에 Soft Delete 방식을 채용했다. 그로 인해 연쇄 삭제 기능은 서비스 레벨에서의 delete() 메서드 조합이나 QueryDsl 커스텀 쿼리를 통해 직접 구현해야 했다. 처음엔, 모든 엔티티가 상속받는 BaseEntity에 존재하는 softDelete() 메서드를 Facade 서비스 클래스에서 전부 호출해서 삭제할까 생각했다. 하지만, 그러면 제공되는 인자는 CarListing.id(판매 차량 id) 한개 뿐일텐데 이걸로 repository 조회해서 연관된 엔티티 id를 얻고 하는 일련의 작업을 서비스 ..

[썬카/백엔드] 차량 관련 Facade 서비스 인터페이스 세분화 (LSP, ISP 원칙)

차량 판매등록 기능은 카히스토리 api를 사용해 받아온 데이터를 등록해야 하지만, api를 아직 도입하지 못해서(너무 비싸..) 임시로 더미 데이터를 입력하는 방식으로 구현했다. 해당 기능은 인터페이스를 통해 구현된 facade 서비스 클래스에 존재하는데, 기존엔 배포용 차량 판매등록 기능과 더미 데이터 판매등록 기능이 하나의 인터페이스에 공존하고 있었고, 그것을 두개의 구현체로 구현했었다. 배포 때는 배포 판매등록 기능, 개발 때는 더미 판매등록 기능이 이용 되어야 하며, 두 기능은 하나의 환경에서 동시에 사용되지 않아야 한다. 따라서 하나의 인터페이스에서 파생된 두 구현체는, 사용되지 않는 메서드까지 상속받아 무의미하게 구현하고 있는 상태였다( ISP 위반 ). 또한 두 구현체는 같은 부모 인터페이스..

[썬카/백엔드] 차량 판매등록 기능 구현 - 더미 데이터 생성과 객체지향적 설계

차량 판매등록 기능을 구현하며 객체지향적 설계를 한 것에 대해 정리해 보고자 한다. 차량 등록에 필요한 엔티티는 10개이며, 판매되는 자동차 1대가 10개 엔티티의 데이터를 전부 필요로 한다. 현재 차량 정보를 조회하는 카히스토리 api는 도입하지 않았기 때문에(너무 비싸..) 도입했다는 가정 하에 api 리턴값과 동일한 형태의 테이블을 설계했고, 그에 맞는 더미 데이터 생성 로직을 작성했다. 그 더미 데이터를 이용해 차량 등록 기능을 구현해 보았다. 다만 엔티티가 너무 많았기 때문에 코드가 길어졌고, 하나의 서비스 클래스에 이 모든 로직을 (엔티티 저장, dto변환, 더미데이터 생성 등) 담는 건 매우 좋지 않은 설계라고 생각되었다. 따라서 각 엔티티별 서비스 클래스에 create 메서드를 각각 만들고..

객체 지향 프로그래밍의 5가지 설계 원칙(SOLID)과 예시 코드

객체 지향 프로그래밍(OOP)에서 지향해야 할 5가지 설계 원칙을 SOLID라고 칭한다. 개인 프로젝트를 시작하면서, 완벽하고 빈틈없는 코드를 짜겠다 라는 목표를 세웠다. 그러나 생각만 하는 것 보다는, 5원칙을 참고하여 좀더 명확한 목표를 잡고 프로그래밍 하는 것이 낫겠다고 느꼈다. 지금까진 SOLID 원칙이 중요하다고 지나가듯이 들었던 말들 뿐이었는데, 이번에 제대로 공부해보며 어째서 중요한 것인지 이해할 수 있었다.  5원칙 중에는 나도 모르게 이미 적용하고 있던 것들도 있었고, 하긴 하는데 왜 하는지는 모르는 것도 있었고, 아예 모르는 것도 있었다. 실무 가서 일하다 보면 혼나고 깨지면서 자동으로 이 5원칙에 따라 코드를 짜게 된다던데, 지금부터 미리 5원칙을 이해하고 코드를 설계할 수 있다면 큰..

Development/Java 2025.03.26

[썬카/백엔드] QueryDSL 도입 및 설정

JPA는 기본적인 CRUD 메서드들을 다양하게 지원하지만, 테이블 간 조인이 복잡하거나 동적 쿼리가 필요한 경우엔 사용하기 어렵다. @Query나 JPQL을 이용해 쿼리를 작성하면 문자열 조합이 필요하기 때문에 오류 가능성이 높아진다. 따라서 안전한 쿼리를 만들기 위해 QueryDSL을 도입했다. QueryDSL- Spring Boot에서 타입 안전한 쿼리를 생성할 수 있게 해주는 프레임워크- Java 코드를 사용하여 SQL, JPQL, MongoDB 쿼리 등 다양한 쿼리를 작성할 수 있게 함- 특히 JPA와 함께 사용될 때 강력한 기능을 발휘 QueryDSL과 타입 안전성의 관계- 타입 안전성 : 코드(쿼리)에서 사용되는 데이터가, 그 데이터에 적합한 타입으로만 보장하는 특성. (숫자는 숫자로, 문자열..

[썬카/백엔드] 예외 전역 핸들러 및 커스텀 예외 구현

비즈니스 로직에서 발생하는 모든 예외를 캐치하고 일관된 형태로 응답하기 위해서, 전역 핸들러와 커스텀 예외를 구현했다.예외 처리 로직을 비즈니스 로직으로부터 분리할 수 있고, 클라이언트는 일관된 형태의 예외를 응답받기 때문에 예외에 대한 처리를 유연하게 할 수 있게 된다.  예외 전역 핸들러(Global Exception Handler)- 애플리케이션에서 발생하는 모든 예외를 일관되게 처리하는 메커니즘- Rest api를 구현한 Spring Boot에서는 @RestControllerAdvice 어노테이션으로 이를 구현한다. 예외 전역 핸들러 - 필요성- 코드 중복 제거 : 각 서비스마다 예외 처리 로직을 반복할 필요 없음, try-catch 블록 최소화- 일관된 오류 응답 : 모든 API에서 일관된 형태..

[독후감] 스프링 부트3 백엔드 개발자 되기: 후기, 스프링 부트 교재

평점: 1/5도서명: 스프링 부트 3 백엔드 개발자 되기 "책"이라는 객체에게 기대되는 기본도 안 되어 있는 책. 책을 끝까지 완독 후 후기를 작성하려 했으나 다른 일정과 겹쳐서 마지막 Git 버전관리와 AWS 배포 부분은 읽지 못했다.그러나 시간이 나더라도 굳이 다시 펼쳐서 끝까지 읽고 싶지는 않은 마음이고...완독하지 못했더라도 가장 중요한 웹사이트는 끝까지 만들어 보았으니 짧은 후기를 쓸 정도는 된다고 생각한다. 독자의 수준이나 기초지식에 따라서 책에 대한 견해가 달라질 수 있으니 나를 설명하겠다.- 정보보안 전공, 보안과 관련된 지식과 네트워크, 서버, 웹 등 기초 CS지식정도 보유.- JAVA, Python 기초문법 숙지한 상태.- "개발"을 해본적은 한번도 없다. 개발 공부는 이 책이 처음. ..

독서/IT 2024.01.15

스프링 입문 - 회원 서비스 테스트

회원 서비스 개발에 이어, 개발한 회원 서비스를 테스트할 차례다. 테스트를 수행할 MemberService에서, Ctrl + Shift + T를 누르고, Create New Test를 누른다. 그러면 이런 창이 뜬다. 테스트 클래스 이름도 본래 클래스 이름에 Test만 붙여서 자동으로 작성해 준다. 내가 테스트하고 싶은 메소드를 아래에서 체크해서 OK를 누른다. 그러면 이렇게 테스트에 필요한 틀을, 적절한 위치(경로)에 아주 쉽게 만들어준다. 일단 만들어진 테스트가 문제가 없는지, 현재 상태에서 바로 한번 돌려본다. 다행히 문제는 없다. 본격적으로 테스트 케이스를 작성해 보기 전에, 잠깐 MemberService로 가보자. 기존 코드를 변경해서, 이렇게 생성자를 통해 외부에서 리포지토리를 주입받도록 변경..

스프링 입문 - 회원 서비스 개발

도메인, 리포지토리를 만들었으니 서비스를 만들 차례이다. hello.hellospring.service 패키지를 만들고, service 패키지 아래에 MemberService 클래스를 만들자. 서비스는 리포지토리와 함께 동작해야 하니, 미리 만들어두었던 리포지토리 객체를 만들어 주자. 회원가입 메소드인 join이다. member 객체를 매개변수로 받아서 리포지토리에 저장하고, 저장한 객체의 Id를 리턴한다. 단, 중복된 name을 가진 회원은 가입할 수 없도록 검증하는 과정이 있다. 바로 밑에 선언해둔 validateDuplicateMember가 중복을 검사하는 메소드이다. name을 기준으로 리포지토리에서 회원을 찾아서, 해당 회원이 이미 존재한다면 "이미 존재하는 회원입니다" 예외를 출력하고 메소드는..

스프링 입문 - 회원 리포지토리 테스트 케이스 작성

개발한 코드가 잘 동작하는지 확인하기 위해서는, 테스트 케이스를 작성하여 확인해야 한다. 자바는 JUnit 이라는 프레임워크를 제공하여, 테스트를 효율적으로 실시할 수 있게 해준다. 우선 테스트 케이스를 작성할 패키지를 만들어 주자. 주의해야 할 점은, 앞서 코드를 작성했던 "Main" 디렉터리 밑이 아닌 그 아래에 있는 "test" 디렉터리 아래에 만들어야 한다는 점이다. test 디렉터리 밑에서, hello.hellospring.repository 패키지를 만들어 주자. repository 패키지 아래에 MemoryMemberRepositoryTest 클래스를 만들어 주자. 우리는 MemoryMemberRepository를 테스트할 것이기 때문에, 뒤에 Test만 붙여서 생성하는 것이다. 테스트 클래..

728x90