본문 바로가기
spring boot

객체 지향 원리

by hyodev 2024. 7. 28.

할인 정책을 애플리케이션에 적용 ---> OrderServiceImpl 코드 고침

 

OrderServiceImpl는 DiscountPolicy 인터페이스에 의존하면서

구체 클래스인 FixDiscountPolicy, RateDiscountPolicy이 의존 (DIP 위반)

 

코드를 고치면 (OCP 위반)

FixDiscountPolicy를 RateDiscountPolicy로 변경하는 순간 OrderServiceImpl의 소스도 같이 변경해야 함

 

AppConfig로 구현 객체 생성하고 연결하도록 만들자!!

 

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 RateDiscountPolicy();
    }
}

 

구현 객체 생성

MemberServiceImpl

MemoryMemberRepository

OrderServiceImpl

FixDiscountPolicy 

 

FixDiscountPolicy->RateDiscountPolicy 객체로 변형

 

생성한 객체 인스턴스의 참조를 생성자를 통해서 주입

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

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

 

MemberServiceImpl -생성자 주입

package hello.core.member;

public class MemberServiceImpl implements MemberService {

    private final MemberRepository memberRepository;

    public MemberServiceImpl(MemberRepository memberRepository){
        this.memberRepository=memberRepository;
    }

    @Override
    public void join(Member member){
        memberRepository.save(member);

    }

    @Override
    public Member findMember(Long memberId){
        return memberRepository.findById(memberId);
    }
}

 

MemoryMemberRepository 를 의존하지 않음

MemberRepository 인터페이스만 의존

MemberServiceImpl 입장에서 생성자를 통해 어떤 구현 객체가 들어올지 알 수 없음

오직 AppConfig에서 결정

 

정리 

AppConfig 리팩터링

구성 정보에서 역할과 구현을 명확하게 분리

역할이 잘 드러남

중복 제거

 

SRP 단일 책임 원칙

- 구현 객체를 생성하고 연결하는 책임 AppConfig가 담당

 

DIP 의존관계 역전 원칙

- OrderServiceImpl는 DiscountPolicy 추상화 인터페이스와 FIxDiscountPolicy 구체화 구현 클래스에도 함께 의존했었다

클라이언트 코드가 DiscountPolicy 추상화 인터페이스에만 의존하도록 함

AppConfig가 FixDiscountPolicy 객체 인스턴스를 클라이언트 코드 대신 생성해서 클라이언트 코드에 의존관계를 주입

 

OCP

- AppConfig가 의존관계를 FixDiscountPolicy 에서 RateDiscountPolicy로 변경해서 클라이언트 코드에 주입하므로 코드는 변경 X

 

IoC(Inversion of Control)

-AppConfig 생성 후에는 구현 객체가 자신의 로직을 실행하는 역할만 담당

 

의존관계 주입 DI

 

정적인 클래스 의존관계

- import 코드만 보고 판단가능

 

동적인 클래스 의존관계

- 런타임에 외부에서 실제 구현 객체를 생성하고 클라이언트를 전달해서 클라이언트와 서버의 실제 의존관계가 연결되는 것을 의존관계 주입이라고 함

- 코드 변경없이 클라이언트가 호출하는 대상의 타입 인스턴스를 변경할 수 있음

 

IoC컨테이너, DI 컨테이너

-AppConfig 처럼 객체를 생성하고 관리하면서 의존관계를 연결해주는 것

- 어샘블러, 오브젝트 팩토리 등으로 불림

 

'spring boot' 카테고리의 다른 글

springboot_JPA_도메인 분석 설계  (0) 2024.09.17
springboot_JPA_프로젝트 환경설정  (0) 2024.09.17
프로젝트 생성  (0) 2024.07.23
스프링 개념  (1) 2024.07.20
회원관리  (0) 2024.07.04