도메인은 모든 사람이 동일한 관점에서 이해할 수 있고 공유할 수 있도록 단순화 시킨것. 객체지향 프로그래밍을 하는 경우 일반적으로 클래스 다이어그램의 표기법을 사용해도 도메인 모델을 정리하는 것이 유용하다.
요구사항 분석과정에서 이해관계자들의 소통도구로 활용

동적인 부분은 고려하지 않은 개발자들이 구체화한 다이어그램

서버가 올라갔을 때 클라이언트가 실제로 사용하는 인스턴스끼리의 참조관계(동적인 부분 포함)


public class RateDiscountPolicy implements DiscountPolicy{
private final int discountPercent = 10;
@Override
public int discount(Member member, int price) {
if(member.getGrade() == Grade.VIP){
return price * 10 / 100;
}else {
return 0;
}
}
}
RateDiscountPolicy를 적용하려면 클라이언트인 OrderServiceImpl도 고쳐야 한다.
public class OrderServiceImpl implements OrderService {
// private final DiscountPolicy discountPolicy = new FixDiscountPolicy();
private final DiscountPolicy discountPolicy = new RateDiscountPolicy();
}
여기서 2가지 문제점이 있다.
이 문제들은 관심사를 분리하여 해결할 수 있다.
public class AppConfig {
private DiscountPolicy discountPolicy() {
return new FixDiscountPolicy();
}
private MemberRepository MemberRepository() {
return new MemoryMemberRepository();
}
public MemberServiceImpl memberService(){
return new MemberServiceImpl(MemberRepository());
}
public OrderServiceImpl orderService(){
return new OrderServiceImpl(MemberRepository(), discountPolicy());
}
}
public class OrderServiceImpl implements OrderService{
private MemberRepository memberRepository;
private DiscountPolicy discountPolicy;
// 생성자 주입
public OrderServiceImpl(MemberRepository memberRepository, DiscountPolicy discountPolicy) {
this.memberRepository = memberRepository;
this.discountPolicy = discountPolicy;
}
}
public class MemberServiceImpl implements MemberService{
private MemberRepository memberRepository;
// 생성자 주입
public MemberServiceImpl(MemberRepository memberRepository) {
this.memberRepository = memberRepository;
}
}


public class AppConfig {
private DiscountPolicy discountPolicy() {
//return new FixDiscountPolicy();
return new RateDiscountPolicy();
}
private MemberRepository MemberRepository() {
return new MemoryMemberRepository();
}
public MemberServiceImpl memberService(){
return new MemberServiceImpl(MemberRepository());
}
public OrderServiceImpl orderService(){
return new OrderServiceImpl(MemberRepository(), discountPolicy());
}
}
@Configuration
public class AppConfig {
@Bean
public DiscountPolicy discountPolicy() {
return new RateDiscountPolicy();
}
@Bean
public MemberRepository MemberRepository() {
return new MemoryMemberRepository();
}
@Bean
public MemberServiceImpl memberService(){
return new MemberServiceImpl(MemberRepository());
}
@Bean
public OrderServiceImpl orderService(){
return new OrderServiceImpl(MemberRepository(), discountPolicy());
}
}
public class MemberApp {
public static void main(String[] args) {
ApplicationContext ac = new AnnotationConfigApplicationContext(AppConfig.class);
MemberService memberService = ac.getBean("memberService", MemberService.class);
Member member = new Member(1L, "memberA", Grade.VIP);
memberService.join(member);
Member findMember = memberService.findMember(1L);
System.out.println("origin : " + member.getName());
System.out.println("find : " + findMember.getName());
}
}