인프런 커뮤니티 질문&답변

최성욱님의 프로필 이미지
최성욱

작성한 질문수

스프링 핵심 원리 - 기본편

싱글톤 패턴

싱글톤 DIP 위반 관련하여 질문합니다

작성

·

458

·

수정됨

0

학습하는 분들께 도움이 되고, 더 좋은 답변을 드릴 수 있도록 질문전에 다음을 꼭 확인해주세요.

1. 강의 내용과 관련된 질문을 남겨주세요.
2. 인프런의 질문 게시판과 자주 하는 질문(링크)을 먼저 확인해주세요.
(자주 하는 질문 링크: https://bit.ly/3fX6ygx)
3. 질문 잘하기 메뉴얼(링크)을 먼저 읽어주세요.
(질문 잘하기 메뉴얼 링크: https://bit.ly/2UfeqCG)

질문 시에는 위 내용은 삭제하고 다음 내용을 남겨주세요.
=========================================
[질문 템플릿]
1. 강의 내용과 관련된 질문인가요? (예/아니오)
2. 인프런의 질문 게시판과 자주 하는 질문에 없는 내용인가요? (예/아니오)
3. 질문 잘하기 메뉴얼을 읽어보셨나요? (예/아니오)

[질문 내용]
여기에 질문 내용을 남겨주세요.
강의에서 싱글톤 패턴 문제점 중에 의존관계상 클라이언트가 구체 클래스에 의존한다(DIP 위반)라고 하셨는데 제가 제대로 이해하고 있는지 알고 싶습니다.
제가 생각하기에는 AppConfig.class파일을 다음과 같이 구성하고,

 

public class AppConfig {


    public MemberService memberservice(){
        return MemberServiceImpl.getInstance();
    }


    public MemberRepository memberRepository(){
        return MemoryMemberRepository.getInstance();
    }


}

MemberSeriveImpl은 MemberRepository를 참조하고 있기 때문에 생성자를 통하여 DI를 하기 때문에, 다음과 같이 코드를 작성하였습니다.

public class MemberServiceImpl {

    private final MemberRepository memberRepository;

    private final static MemberService memberService = new MemberServiceImpl();


    public MemberService getInstance(){
        return memberService;
    }


    private MemberServiceImpl(MemberRepository memberRepository) {
        this.memberRepository = MemoryMemberRepository.getInstance();
    }
}

 

그 결과 Client인 MemberServiceImpl 입장에서는 MemoryMemberRepository를 주입하기 위하여 어쩔수 없이 구체 클래스(MemoryMemberRepository.class)를 의존할 수 밖에 없는것 같습니다.(싱글톤 패턴을 유지하기 위해 미리 의존관계등을 미리 세팅해야됨)
제가 제대로 이해한건지 맞는지 알고싶습니다

답변 1

1

안녕하세요, 인프런 AI 인턴입니다.

최성욱님의 질문에 대한 답변 드리겠습니다.

네, 강의 내용과 관련된 질문이며 인프런의 질문 게시판이나 자주 하는 질문에 없는 내용으로 보입니다. 질문 잘하기 메뉴얼을 읽어보신 것으로 가정하고 답변 진행하겠습니다.

먼저 DIP(Dependency Inversion Principle, 의존관계 역전 원칙)는 고수준의 모듈이 저수준의 모듈에 의존해서는 안 되며, 둘 다 추상화에 의존해야 한다는 원칙입니다. 여기서 말하는 ‘고수준 모듈’이란 비즈니스 로직을 수행하는 클래스를, ‘저수준 모듈’이란 데이터를 저장하는 등의 기술적인 세부사항을 담당하는 클래스를 말합니다.

최성욱님이 제시한 코드에서는 MemberServiceImpl이 싱글톤으로 구현되면서 스스로가 MemoryMemberRepository의 싱글톤 인스턴스를 직접 생성하고 있습니다. 이는 실제로 DIP를 위반하는 것이 맞습니다. MemberServiceImplMemberRepository 인터페이스에 의존해야 하는데, 대신 구체 클래스인 MemoryMemberRepository를 직접 참조하고 있기 때문입니다.

DIP를 위반하지 않으려면 MemberRepository의 구현체를 외부에서 MemberServiceImpl에 주입해야 하며, 이때 싱글톤 패턴을 구현하는 방식 역시 이러한 의존관계 주입이 가능하도록 해야 합니다. 보통은 스프링 프레임워크가 이러한 의존관계를 자동으로 관리해 주기 때문에 구현체를 직접 참조하는 것이 아니라, 스프링 빈으로 등록하여 주입받게 됩니다.

제시하신 코드에서는 AppConfig에서 싱글톤 객체를 생성할 때 사용하는 방식에 대해 다시 고민해 볼 필요가 있습니다. 실제로 스프링 프레임워크를 사용한다면 이러한 싱글톤 관리는 스프링 컨테이너가 알아서 해주기 때문에, 개발자는 구현 클래스가 아닌 인터페이스에만 의존하도록 서비스를 구현하는 데 집중할 수 있습니다.

따라서 MemberServiceImpl 클래스에서 싱글톤을 구현할 필요 없이 스프링 빈으로 등록하여 사용하면, DIP를 준수하면서도 싱글톤 보장을 받을 수 있습니다.

최성욱님의 프로필 이미지
최성욱

작성한 질문수

질문하기