Singleton VS DI

2024. 2. 12. 18:04·프로그래밍 언어/C#

✅ Singleton VS DI

Singleton

  • GoF 책에서 나온 가장 기본적인 디자인 패턴
  • 싱글톤은 응용 프로그램 전체 수명 동안 어떤 클래스의 인스턴스를 하나만 가지는 것을 의미하는 디자인 패턴이다
  • 싱글톤을 사용하는 것은 본질적으로 나쁜 것은 아님.

일반적인 구현 방법

public class BankGateway
{
    public readonly static BankGateway Instance = new BankGateway();
 
    private BankGateway()
    {
    }
 
    public void TransferMoney()
    {
        /* Transferring money */
    }
}
  • private를 생성자로 가지며, Instance 참조를 통해 인스턴스를 유일하게 가져올 수 있다.
  • static이기 때문에 응용 프로그램 프로세스가 실행 중인 한 계속 유지 된다. (응용 프로그램의 수명에 바인딩 됨)
  • 그렇기 때문에 지연 로딩을 지원하지 않는다.
    • 객체는 필요 여부에 관계 없이 로드 시에 인스턴스 된다. (실제로는 조금 더 복잡하다)

단점

  • 종속성 주입 원칙과 모순되어 테스트 가능성 방해
  • 전역 상수로 작동하기 때문에 필요할 때 대체하기 어렵다.
    • 싱글턴을 부를때마다 실제(Origin) 데이터로 불러오기 때문에 테스트가 어려움
    • 이것은 유닛 테스트시 피해야 하는 것 중 하나이다.
  • 애플리케이션이 항상 모든 것을 메모리에 유지하게 된다.

Dependency Injection

  • 객체에 의존성을 전달하는 디자인 패턴

일반적인 구현 방법

public interface IBankGateway
{
    void TransferMoney();
}
 
public class BankGateway : IBankGateway
{
    public void TransferMoney()
    {
        /* Transferring money */
    }
}
 
public class Processor
{
    private readonly IBankGateway_gateway;
 
    public Processor(IBankGateway gateway)
    {
        _gateway = gateway;
    }
 
    public void Process()
    {
        _gateway.TransferMoney();
    }
}
  • 이 코드는 테스트 가능하다.
  • 가짜 BankGateway를 만들고 프로세서에 전달해서 돈을 이체하는지 확인할 수 있다.
    • 실제 은행 게이트웨이에는 호출이 이루어지지 않는다.

기본 클래스 외부에 객체를 만들어야 하는 이유?

  • 코드를 완전히 테스트 가능하다.
    • 언제나 필요한 스크립트의 동작이 포함된 다른 구현으로 대체할 수 있다.
  • 생성 작업과 사용 작업의 분리가 가능하다.
  • 클래스에 제공되는 종속성 유형을 제어할 수 있다.
    • DI 컨테이너를 사용하면 저장된 종속성 유형을 정의하고, 이를 약한 링크, 직접 링크, 또는 싱글톤 유형의 링크로 전송할 수 있다.

Singleton vs Dependency Injection

  • 대부분의 경우 Dependency Injection이 선호된다.
  • non-stable한 dependency가 있다면 해당하는 의존성을 주입해서 종속 클래스가 필요한 것을 명시적으로 지정하는 것이 좋다.
    • non-stable dependency : 전역 상태를 참조하는 것
      • ex) external service, file system, database,,,

싱글턴을 사용하는 것이 더 나은 경우

  • 환경 의존성(Ambient dependencies)
    • 여러 클래스 및 레이어에 걸친 의존성
    • 이런 종류의 의존성에 대해서는 의존성 주입 패턴을 적용하는 것에 별로 의미가 없다. 왜냐하면 어디에나 존재할 것이기 때문이다.
     

  • 세가지 서비스 각각 의존성 #1이 존재한다. → 싱글턴 추출 가능

  • 의존성 제거를 통해 전체 그래프를 단순하게 만들었다.
❓ 싱글턴을 도입해야 하는 경우 의존성이 대부분의 클래스 및 응용 프로그램의 여러 레이어를 횡단하는 경우 싱글턴을 사용해서 해당 의존성을 추출할 수 있다.

결론

  • Singleton과 DI를 사용할 땐 주입된 의존성 사이의 균형을 유지하는 것이 중요하다.
    • singleton 사용 : 의존성이 많은 클래스와 레이어에서 사용되는 경우
    • di 사용 : 이 외에 사용

📜참고자료

Singleton vs Dependency Injection

Dependency injection and Singleton. Everything you need to know and a little more

'프로그래밍 언어 > C#' 카테고리의 다른 글

컴파일 타임 상수와 런타임 상수: 어떤 것을 사용해야 할까?  (0) 2024.02.29
C#에서 var를 사용하는 이유와 주의사항  (0) 2024.02.26
비동기 프로그래밍  (0) 2023.12.25
람다식 () =>  (0) 2023.11.01
C#과 .NET Framework  (0) 2023.10.08
'프로그래밍 언어/C#' 카테고리의 다른 글
  • 컴파일 타임 상수와 런타임 상수: 어떤 것을 사용해야 할까?
  • C#에서 var를 사용하는 이유와 주의사항
  • 비동기 프로그래밍
  • 람다식 () =>
가든_
가든_
  • 가든_
    Code Garden
    가든_
  • 전체
    오늘
    어제
    • 글 목록 (60)
      • 프로그래밍 언어 (11)
        • JAVA (0)
        • C++ (2)
        • C# (9)
      • 개발툴 (24)
        • Visual Studio (0)
        • Visual Studio Code (1)
        • Eclipse (1)
        • Unity (19)
        • Unreal (0)
        • Spring (1)
        • SpringBoot (0)
        • Vue (2)
      • 디자인 패턴 (6)
      • 백엔드 (4)
        • MySQL (1)
        • Servlet (3)
      • 프론트엔드 (4)
        • HTML (3)
        • CSS (0)
        • Javascript (1)
      • 알고리즘 (10)
        • 공식 (3)
        • 백준 (6)
        • SW Expert Academy (1)
  • 블로그 메뉴

    • 홈
    • 태그
    • 방명록
  • 링크

  • 공지사항

  • 인기 글

  • 태그

    Java
    12738
    Adapter 패턴
    Proxy 패턴
    chatGPT
    런타임 상수
    상태공간트리
    DI
    구조패턴
    다이어그램 그리기
    오브젝터 어댑터
    Adaptee
    스택
    Reflex
    UniRX
    HTML
    Factory 패턴
    SetTile
    행동 UML 다이어그램
    컴파일 상수
    FixedUpdate
    swea2112
    ()=>
    구조적 UML 다이어그램
    Abstract Factory 패턴
    c#
    클래스 어댑터
    RDBM
    Unity
    MVC
  • 최근 댓글

  • 최근 글

  • hELLO· Designed By정상우.v4.10.3
가든_
Singleton VS DI
상단으로

티스토리툴바