Singleton[Design Pattern]

SnowCat·2023년 3월 2일
0

Design Pattern

목록 보기
6/23
post-thumbnail

의도

  • 클래스에 인스턴스가 하나만 있도록 하면서 인스턴스에 대한 전역 접근 지점을 제공하는 생성 디자인 패턴

문제

한번에 두가지 문제를 해결 -> 단일 책임 원칙 위반에 유의

  1. 클래스에 인스턴스가 하나만 있도록 하기
  • 데이터페이스, 파일 등 공유 리소스에 대한 접근을 제어할 필요가 있음
  • 기존의 객체를 생성하는 방법으로는 생성자 호출이 반드시 필요하고 이는 새 객체 반환으로 이어지게 됨
  1. 인스턴스에 대한 전역 접근 지점 제공
  • 전역변수를 사용하면 모든 코드가 해당 변수의 내용을 덮어써 충돌 위험이 발생할 수 있음
  • 하나의 인스턴스에 여러 값을 저장해 코드를 정리할 필요가 있음

최근에는 둘중 하나의 문제만 해결하는 경우도 싱글턴이라 부르기도 함

해결책

  • 싱글턴의 모든 구현은 다음의 두 단계를 가짐
    • 다른 객체들이 싱글턴 클래스와 함께 new 연산자를 사용하지 못하도록 디폴트 생성자를 비공개로 설정
    • 생성자 역할을 하는 정적 생성 메서드 생성
      생성 메서드는 비공개 생성자를 호출한 후 객체를 정적 필드에 저장함
      메서드에 대한 다음 호출들은 모두 캐시된 객체 반환

구조


class Singleton {
  
  // getter만을 통해 접근가능한 인스턴스를 생성해 캐시 역할로 사용
    private static instance: Singleton;

  // 전역 변수 값을 저장하지만 수정은 불가능하게 생성자를 private로 사용
    private constructor() { }

  // 이제 static 생성 메서드를 통해 받아낸 값은 항상 동일하면서 수정이 불가능하게 됨
    public static getInstance(): Singleton {
        if (!Singleton.instance) {
            Singleton.instance = new Singleton();
        }

        return Singleton.instance;
    }

    public someBusinessLogic() {
        // ...
    }
}

function clientCode() {
    const s1 = Singleton.getInstance();
    const s2 = Singleton.getInstance();

  //Singleton works, both variables contain the same instance.
    if (s1 === s2) {
        console.log('Singleton works, both variables contain the same instance.');
    } else {
        console.log('Singleton failed, variables contain different instances.');
    }
}

clientCode();

적용

  • 프로그램의 클래스에 모든 클라이언트가 사용할 수 있는 단일 인스턴스만 있어야 할 때 사용
    특별 생성 메서드를 제외한 다른 생성 수단을 비활성화함
    새 객체를 생성하거나, 객체가 있으면 객체를 반환해주기만 함
  • 변수들을 더 엄격하게 제어해야 할 때 사용
    전역 변수들과 달리 싱글턴 패턴을 사용하면 클래스의 인스턴스가 하나만 있도록 보장해 줌 -> 캐시된 인스턴스는 어떤것과도 대체될 수 없음

구현 방법

  1. 클래스에 싱글턴 인스턴스를 저장할 비공개 static 인스턴스 추가
  2. 싱글턴 인스턴스를 가져오기 위한 static 생성 메서드 선언
  3. 메서드 내에서 지연된 초기화, 즉 첫 호출 이후 객체를 생성해 private field에 넣도록 하는 로직을 구현함
  4. 클래스의 생성자를 비공개로 만들어 클래스만이 생성자를 호출할 수 있도록 함
  5. 클라이언트 코드의 싱글턴 생성자에 대한 직접 호출을 싱글턴의 static 생성 메서드 호출로 변경

장단점

  • 클래스가 하나의 인스턴스만을 갖는다는 것을 확신할 수 있음
  • 인스턴스에 대한 전역 접근 지점을 얻을 수 있고, 객체는 처음 요청할 때만 초기화됨
  • 단일 책임을 위반하며, 잘못된 디자인이 있는 경우 이를 가릴 수 있음
  • 다중 스레드 환경일 경우 여러 스레드가 싱글턴 객체를 여러번 생성하지 않도록 처리해주어야 함
  • 싱글턴의 클라이언트 코드를 유닛 테스트하기 어려울 수 있음
    많은 테스트 프레임워크들이 모의 객체들을 생성할 때 상속에 의존하기 때문
profile
냐아아아아아아아아앙

0개의 댓글