목록분류 전체보기 (71)
kongkong.note
CQRS (Command Query Responsibility Segregation)쓰기(Command)와 읽기(Query)를 모델·책임·경로까지 분리하는 것보통 조회할 때는 2개 이상의 aggregate 가 필요하기 때문실무 사용 예시 : 조회는 QueryDSL / MyBatis, 쓰기는 JPA// Commandpublic void approveTuition(Long id) { TuitionApplication app = repo.findById(id); app.approve();}// Querypublic TuitionDetailDto getTuition(Long id) { return queryRepository.findDetail(id);}
이벤트바운디드 컨텍스트 간 강한 결합 제거 목적스프링에서 제공하는 ApplicationEventPublisher 활용이벤트 구성 요소이벤트 생성 주체(이벤트 발생) -> 이벤트 디스패처(이벤트 전달)-> 이벤트 핸들러(이벤트 처리)이벤트 이름과거시제를 사용. ex) ChangedEvent{}이벤트 장점서로 다른 도메인 로직이 섞이는 것을 방지, 의존성 제거❌ 강결합 예시// Tuition Contextpublic class TuitionService { private final ApprovalService approvalService; // 다른 컨텍스트 직접 의존 ❌ public void approve(Long tuitionId) { TuitionApplication app = ..
바운디드 컨텍스트란?어디까지가 같은 도메인 모델을 쓰는 범위인지 정해 놓은 경계같은 용어와 모델이 ‘동일한 의미’로 통용되는 명확한 경계❌ 바운디드 컨텍스트 없을 때class Order { PaymentStatus paymentStatus; DeliveryStatus deliveryStatus; BigDecimal settlementAmount; String trackingNumber;} 주문 + 결제 + 배송 + 정산 다 섞임“이 필드 누가 책임지지?”가 불분명✅ 바운디드 컨텍스트 나눈 후주문 컨텍스트Order { OrderId OrderItems OrderStatus} 결제 컨텍스트Payment { PaymentId OrderId PaymentSt..
8.2 선점 잠금(Pessimistic Lock)먼저 애그리거트를 구한 스레드가 애그리거트 사용이 끝날 때까지 다른 스레드가 해당 애그리거트를 수정하지 못하게 막는 방식보통 DBMS의 행단위 잠금을 활용 - 특정 레코드에 한 커넥션만 접근할 수 있도록스프링 데이터 JPA : @Lock(), @QueryHint() 활용 8.3 비선점 잠금(Optimistic Lock)변경한 데이터를 실제 DBMS에 반영하는 시점에 변경 가능 여부를 확인하는 방식스프링 데이터 JPA : @Version() 활용 8.4 오프라인 선점 잠금여러 트랜잭션에 걸쳐 동시 변경을 방지하는 방식(누군가 수정 중일 때 다른 사람은 수정을 못하게 막는 것)선점 vs 비선점 : 기본은 비선점 잠금비선점 잠금 : DB Lock 안잡음, ex)..
7.2 도메인 서비스주로 아래 상황에서 도메인 서비스 사용도메인의 의미가 드러나는 용어와 타입으로 생성(ex_ DiscountCaculationService)계산 로직 : 여러 애그리거트가 필요하거나 한 애그리거트에 넣기에는 다소 복잡한 로직외부 시스템 연동이 필요한 도메인 로직도메인 영역의 (애그리거트, 밸류)와 (도메인 서비스) 차이는 도메인 서비스는 상태 없이 로직만 구현한다는 점예시 : 실제 결제 금액 계산 로직은 '주문', '상품', '할인', '회원' 애그리거트와 연관이 있다. 이 때 어느 한 애그리거트에서 해당 로직을 구현하게 되면 종속적이게 되므로, 별도 도메인 서비스를 구현한다는 것.
사용자 → 표현 영역(Controller) → 응용 영역(Service) → 도메인 영역6.2 응용 서비스의 역할응용 서비스의 주요 역할 : 도메인 객체를 사용해서 사용자의 요청을 처리도메인의 상태 변경을 트랜잭션(@Transaction)으로 처리해야 한다. 트랜잭션 범위에서 응용 서비스를 실행해야 한다. 응용 서비스는 도메인 로직을 구현하지 않는다. 도메인 로직은 도메인 영역에 모아서 코드 중복을 줄이고 응집도를 높여야 한다. 6.3 응용 서비스의 구현응용 서비스는 표현 영역 도메인 영역을 연결하는 매개체 역할. 응용 서비스 자체는 복잡한 로직을 수행하지 않는다.한 도메인과 관련된 기능을 한 클래스에 위치 : 장점 ) 코드 중복 제거 용이단점 ) 한 서비스 클래스의 크기가 커짐한 도메인과 관련된 기능..
* 스프링 데이터 JPA 기술로만 책 설명이 되어 있고, 실무와는 차이가 있음CQRS : 명령 모델, 조회 모델을 분리하는 패턴Specification : 검색조건을 표현하기 위한 인터페이스=> 실무에서는 QueryDSL(Q객체) 또는 MyBatis 사용sort 파라미터 : 정렬 => 실무에서는 QueryDSL 쿼리 또는 enum으로 제한(switch문으로 QueryDSL 정렬 구문 추가)Pageable : 페이징 처리를 위한 타입=> 실무에서는 Pageable 객체는 받되, 참고용(요청 규격용)으로만 사용 QueryDSL에서 .offset(), .limit() 처리 무한 스크롤은 Pageable 사용하지 않고 QueryDSL의 .limit() 처리
4.1 JPA를 이용한 리포지터리 구현리포지터리 인터페이스는 애그리거트와 같이 도메인 영역에 속하고, 리포지터리를 구현한 클래스는 인프라 스트럭처 영역에 속한다.리포지터리 구현 클래스를 인프라 스트럭처 영역에 위치시켜서 인프라 스트럭처에 대한 의존을 낮춰야 한다.리포지터리 인터페이스는 애그리거트 루트를 기준으로 작성 4.3 매핑 구현밸류는 불변타입이므로 set 메서드를 제공하지 않아 기본 생성자가 불필요하지만, JPA에서는 protected 기본 생성자를 추가해줘야 한다.(JPA 기술 제약 - JPA는 public 또는 protected 기본 생성자 지원)AttributeConverter : 밸류 타입과 DB 컬럼 데이터 간의 변환을 처리식별자 의미를 강조하기 위해서 밸류 타입으로 지정하기도 하며, 이 ..