8. 언어의 발전
• 도메인에대한새로운이해
• 코드에반영,언어에반영
public class Order {
public voidchangeShippingInfo(
ShippingInfonewShippingInfo){
if (state== OrderState.PAYMENT_WAITING||
state== OrderState..PREPARING){
this.shippingInfo= newShippingInof;
} else {
thrownew IllegalStateException();
}
}
public class Order {
public voidchangeShippingInfo(
ShippingInfonewShippingInfo){
verifyNotYetShipped();
this.shippingInfo = newShippingInof;
}
public voidcancel() {
verifyNotYetShipped();
this.state= OrderState.CANCELED;
}
privatevoid verifyNotYetShipped(){
if (state!= OrderState.PAYMENT_WAITING&&
state!= OrderState.PREPARING)
throw new IllegalStateException();
}
"결제대기거나물건준비중일때"
배송지를변경할수있다.
"배송을아직하지않았으면"
배송지를변경할수있다,주문을취소할수있다.
8DDD 소개@서문래
22. (DDD의) 영역
영역 설명
표현(UI) 사용자의 요청을 해석해서 다른 영역에 처리를
위임하고, 결과를 사용자에 알맞게 변환해서
전달한다.
사용자에게 보여지는 흐름을 제어한다.
응용 사용자의 요청을 처리할 기능을 구현한다. 처
리 흐름을 구현하며, 도메인 로직은 도메인 영
역에 위임한다.
도메인 도메인 로직을 구현한다. 엔티티, 밸류, 애그리
거트, 리포지토리, 도메인 서비스가 위치한다.
인프라스트럭처 DBMS 연동, REST 클라이언트와 같은 구현 기
술을 다룬다. DIP 구조에서 저수준 모듈이 이
영역에 위치한다.
22DDD 소개@서문래
52. 응용 서비스의 구현
• 도메인객체를사용한기능구현
• 리포지토리에서애그리거트루트를구하고
• 애그리거트루트의기능을실행
@Service
public class ActivateOperatorService {
private OperatorRepository operatorRepository;
@Transactional
public void activate(String operatorId) {
// 애그리거트 루트를 구하고
Operator operator = operatorRepository.findOne(operatorId);
if (operator == null)
throw new OperatorNotFoundException();
// 도메인 기능을 실행
operator.activate();
}
52DDD 소개@서문래
53. 응용 서비스의 입력과 출력
• 메서드파라미터
• 기능을수행하는데필요한데이터
public class ChangePasswordService {
public void changePassword(
String id,
String curPw,
String newPw) {
Member member = findMember(id);
member.changePassword(curPw, newPw);
}
...
public class PlaceOrderService {
public OrderNo placeOrder(OrderRequest req) {
OrderNo id = createNextOrderNo();
Order order = createOrder(id, req);
orderRepository.save(order);
return id;
}
...
* 도메인의 엔티티를 서비스의 파라미터로 사용하지 말 것
* 딱 들어맞는 경우로만 제한
53DDD 소개@서문래
54. 응용 서비스의 입력과 출력
• 리턴
• 요청처리결과를사용자에게보여줄경우응답제공
• 예,새로생성한주문의ID,주문목록
• 고민거리
• 도메인객체리턴vsUI에노출할데이터만담은객체리턴
• 구현편의성,팀표준,성능등고려
• 조회전용모델검토
• 익셉션은실패를의미
• 응용서비스나도메인에서발생
54DDD 소개@서문래
55. 응용 서비스와 트랜잭션
• 트랜잭션담당
public class ChangePasswordService {
@Transactional
public void changePassword(ChangePasswordRequest request) {
Member member = findExistingMember(request.getMemberId());
member.changePassword(
request.getCurrentPassword(),
request.getNewPassword());
}
...
* 고민거리 : Open Session In View
55DDD 소개@서문래
56. 응용 서비스에 도메인 로직 넣지 않기
• 도메인로직이나제약을구현하면안됨!
public class ActivateOperatorService {
private OperatorRepository operatorRepository;
@Transactional
public void activate(String operatorId) {
Operator operator = operatorRepository.findOne(operatorId);
if (operator == null)
throw new OperatorNotFoundException();
if (operator.isDeleted() || operator.isActivated()) {
throw new RuntimeException();
}
operator.setActivated(true);
// operator.activate()에 들어가야 할 제약 검사
}
56DDD 소개@서문래
57. 몇 가지 고민할 것
• 서비스
• 크기
• 도메인단위로기능몰아넣기vs기능군별로서비스구분
• 인터페이스필요여부
• 인터페이스 +구현클래스
• 그냥클래스만
• 서비스vs표현vs도메인
• 값검증
• 권한검사
57DDD 소개@서문래