2019년에 했던 '스프링 가이드' (스터디 자료로 공유된 내용은 비공개이므로 해당 repository를 공유) 스터디 내용을 바탕으로 내용을 정리하고자 한다. 모든 것을 100%로 이해했다고 생각하진 않지만, 이해한 내용을 바탕으로 정리하려고 한다.😊
1회차 내용은 디렉토리구조 라는 주제였다. 디렉토리 구조와 더불어 객체&도메인에 대한 내용도 다루었는데, 그 이후에 사내에서 진행한 프로젝트에 많은 영향을 주었던 내용이다.
도메인 끼리는 응집력이 높아야 한다. (즉, 유사한 성격의 도메인끼리는 함께 있는 것이 좋다는 의미이다.) 따라서, 한 곳에 때려박기 식 디렉토리 구조는 좋지 않다. (도메인 응집력이 높아질수록 직관적이며, 해당 도메인을 이해하기 쉬워진다.) 이러한 관점에서 '도메인 형' 디렉토리 구조를 더 좋은 구조라고 생각한다.
아래의 예제는 우리가 쇼핑 사이트를 개발한다고 상상하고 보자.
🙋♀️ 요구사항 : 주문은 상품이 있어야 주문이 가능하다.
👩💻 개발자 관점 : 상품 기반으로 주문을 만들어야 한다.
@Getter
public class Order {
private Long id;
private Address address;
private Orderer orderer;
private List<OrderItem> orderItems = new ArrayList<>();
public Order(Address address, Orderer orderer, List<ProductItem> productItems) {
Assert.notNull(address, "address must not be null");
Assert.notNull(orderer, "orderer must not be null");
Assert.notEmpty(orderItems, "orderItems must not be empty");
this.address = address;
this.orderer = orderer;
for(ProductItem productItem : productItems) {
orderItems.add(new OrderItem(productItem));
}
}
}
exception
처리하자🙋♀️ 요구사항 : 회원 주문 / 비회원 주문이 있다.
👩💻 개발자 관점 : 해당 요구사항을 최대한 코드로 해석 가능하게 작성하자.
@Getter
@NoArgsConstructor
public class Orderer {
private Long id;
private String name;
private Orderer(Long id, String name) {
Assert.notNull(name, "name must not be null");
this.id = id;
this.name = name;
}
public static Orderer memberOrderer(Long id, String name) {
Assert.notNull(id, "id must not be null");
return new Orderer(id, name);
}
public static Orderer nonMemberOrderer(String name) {
return new Orderer(name);
}
}
memberOrderer
) / 비회원 주문(nonMemberOrderer
)의 객체 생성을 분리 (보다 직관적인 코드를 만들 수 있다.)