tech/Spring

[Spring] 좋은 AppConfig 설계

sunm2n 2025. 7. 19. 09:56
package hello.core;

import hello.core.discount.FixDiscountPolicy;
import hello.core.member.MemberService;
import hello.core.member.MemberServiceImpl;
import hello.core.member.MemoryMemberRepository;
import hello.core.order.OrderService;
import hello.core.order.OrderServiceImpl;

public class AppConfig {

    public MemberService memberService() {
        return new MemberServiceImpl(new MemoryMemberRepository());

    }

    public OrderService orderService() {
        return new OrderServiceImpl(
                new MemoryMemberRepository(),
                new FixDiscountPolicy());
    }
}

 

 

 

다음 AppConfig를 보면 위와 같은 그림이 잘 나타나 있는가?

 

아니다.

 

중복을 제거하고 역할에 따른 구현이 보이도록 리팩토링이 필요하다.

 

package hello.core;

import hello.core.discount.DiscountPolicy;
import hello.core.discount.FixDiscountPolicy;
import hello.core.member.MemberRepository;
import hello.core.member.MemberService;
import hello.core.member.MemberServiceImpl;
import hello.core.member.MemoryMemberRepository;
import hello.core.order.OrderService;
import hello.core.order.OrderServiceImpl;

public class AppConfig {

    public MemberService memberService() {
        return new MemberServiceImpl(memberRepository());
    }

    private MemberRepository memberRepository() {
        return new MemoryMemberRepository();
    }

    public OrderService orderService() {
        return new OrderServiceImpl(
                memberRepository(),
                discountPolicy());
    }

    public DiscountPolicy discountPolicy() {
        return new FixDiscountPolicy();
    }
}

 

new MemoryMemberRepository() 이 부분이 중복 제거되었다. 이제 MemoryMemberRepository() 를 다른 구현체로 변경할 때

 

한 부분만 변경하면 된다.

 

이렇게 구조를 리팩토링하면 역할과 구현클래스가 한눈에 들어온다.

 

따라서 애플리케이션 전체 구성이 어떻게 되어있는지 빠르게 파악할 수 있다.

 

 

 

 

그리고 이제 할인 정책을 바꿔보려고 한다.

 

FixDiscountPolicy -> RateDiscountPolicy

 

 

어느 부분만 변경하면 될까?

 

AppConfig의 등장으로 애플리케이션이 크게 사용 영역과, 객체를 생성하고 구성(Configuration)하는 영역으로 분리했다.

 

 

우리는 사용 영역에 대해 단 한줄의 코드도 손대지 않고 할인 정책을 바꿀 수 있게 되었다.

 

package hello.core;

import hello.core.discount.DiscountPolicy;
import hello.core.discount.FixDiscountPolicy;
import hello.core.discount.RateDiscountPolicy;
import hello.core.member.MemberRepository;
import hello.core.member.MemberService;
import hello.core.member.MemberServiceImpl;
import hello.core.member.MemoryMemberRepository;
import hello.core.order.OrderService;
import hello.core.order.OrderServiceImpl;

public class AppConfig {

    public MemberService memberService() {
        return new MemberServiceImpl(memberRepository());
    }

    private MemberRepository memberRepository() {
        return new MemoryMemberRepository();
    }

    public OrderService orderService() {
        return new OrderServiceImpl(
                memberRepository(),
                discountPolicy());
    }

    public DiscountPolicy discountPolicy() {
//        return new FixDiscountPolicy();
        return new RateDiscountPolicy();
    }
}

 

이렇게 코드 한줄 수정만으로 할인 정책을 바꾸었다.

'tech > Spring' 카테고리의 다른 글

[Spring] @ActiveProfiles("test") vs @DataJpaTest  (0) 2025.08.21
[Spring] @Builder(toBuilder = true)  (1) 2025.07.24
[Spring] N + 1 문제  (1) 2025.07.18
[Spring] Config  (0) 2025.07.09
[Spring] SOLID 원칙을 잘 지키고 있는가  (0) 2025.07.04