디자인 패턴: 싱글톤 패턴

Intro to Design Patterns 시리즈 계속; 오늘은 싱글톤 디자인 패턴에 대해 설명하겠습니다.

애플리케이션에 하나의 전역 변수를 가질 수 있는 방법을 알고 있습니까? 싱글톤 패턴은 클래스에 대해 동일하지만 동일합니다.

Singleton 디자인 패턴은 생성 패턴이며 실제로는 매우 간단한 패턴입니다. 기본적으로 애플리케이션에 클래스의 인스턴스가 하나만 필요한 경우 싱글톤 패턴을 사용하는 경우입니다. 싱글톤 패턴은 애플리케이션에서 하나의 인스턴스만 가질 수 있는 클래스입니다.

문제



여기서는 카운터의 간단한 예를 사용하겠습니다. 대화방이 있고 데이터베이스를 사용하지 않고 현재 온라인 상태인 사람 수를 세고 싶다고 가정해 보겠습니다. 단순함을 위해 해당 정보가 영구적일 필요가 없다고 가정하고 애플리케이션이 다시 시작될 때 카운터를 재설정해도 괜찮습니다. 이 경우 사용자 수를 추적하는 변수가 있는 클래스를 사용할 수 있습니다. 클래스는 다음과 같이 보일 수 있습니다.

class UserCount {
  private counter int;

  constructor UserCount(){
    this.counter = 0;
  }

  function Increment() {
    this.counter++;
  }

  function Decrement() {
    this.counter--;
  }
}

class Auth {
  counterInstance UserCount;

  constructor Auth() {
    this.counterInstance = new UserCount();
  }

  function Login(request){
    // Check username and password then log the user in
    this.counterInstance.Increment()
  }

  function Logout(request){
    // Logout the user
    this.counterInstance.Decrement()
  }
}



그 구현으로 우리는 0으로 초기화되는 하나의 변수가 있는 클래스를 갖게 됩니다. 그런 다음 증가 및 감소할 수 있습니다.
Class Auth는 이 클래스를 사용하며 사용자가 로그인할 때마다 숫자가 증가하고 로그아웃할 때마다 숫자가 감소합니다.

사용자가 로그인할 때만 계산되고 UserCounter 클래스를 사용하는 클래스가 하나만 있기 때문에 이것은 우리의 경우에 잘 작동합니다. 그러나 이제 사용자가 로그인하지 않고도 채팅할 수 있는 채팅에 게스트를 추가할 수 있습니다.

이제 UserCounter 클래스를 사용해야 하는 새 클래스 GuestChat이 있습니다. UserCounter의 동일한 구현을 사용하는 경우 각 클래스에는 UserCounter 클래스의 고유한 인스턴스가 있기 때문에 고유한 독립 카운터가 있습니다.

class GuestChat {
  counterInstance UserCount;

  constructor GuestChat() {
    this.counterInstance = new UserCount();
  }

  function AddGuest() {
    // Create a new guest
    this.counterInstance.Increment();
  }

  function RemoveGuest() {
    // Remove a guest
    this.counterInstance.Decrement();
  }
}


해결책



다음은 싱글톤 패턴입니다. UserCounter의 여러 인스턴스를 갖는 대신에 하나의 인스턴스만 생성하고 인스턴스가 존재할 때마다 모든 클래스가 이를 사용하는 클래스를 구현할 수 있습니다. 구현은 다음과 같습니다.

class UserCount {
  private static instance UserCount;
  private counter int;

  static function GetInstance() {
    if (this.UserCount == null) {
      this.instance = new this.UserCount();
      return this.instance;
    } else {
      return this.instance;
    }
  }

  private constructor UserCount(){
    this.counter = 0;
  }

  function Increment() {
    this.counter++;
  }

  function Decrement() {
    this.counter--;
  }
}


다음은 UserCount 클래스에 적용한 변경 사항입니다.
  • 새 개인 변수를 만들고instance 정적으로 만듭니다. 정적 변수와 정적 함수는 개체가 아니라 클래스 자체와 연결됩니다. 따라서 클래스가 호출될 때마다 동일한 정적 변수/함수를 참조합니다.
  • 생성자를 비공개로 만드십시오. 이런 식으로 다른 클래스는 클래스의 새 인스턴스를 만들 수 없으며 새 인스턴스를 만드는 시기를 결정하는 것은 전적으로 클래스 자체에 달려 있습니다.
  • 인스턴스가 이미 생성된 경우 인스턴스를 반환하는 새 함수를 생성GetInstance하거나 존재하지 않는 경우 새 인스턴스를 생성합니다(개인 생성자 사용).

  • 이제 클래스 Auth 및 GuestChat이 다음과 같이 변경됩니다.

    class Auth {
      counterInstance UserCount;
    
      constructor Auth() {
        this.counterInstance = UserCount.GetInstance();
      }
    
      function Login(request){
        // Check username and password then log the user in
        this.counterInstance.Increment()
      }
    
      function Logout(request){
        // Logout the user
        this.counterInstance.Decrement()
      }
    }
    
    
    class GuestChat {
      counterInstance UserCount;
    
      constructor GuestChat() {
        this.counterInstance = UserCount.GetInstance();
      }
    
      function AddGuest() {
        // Create a new guest
        this.counterInstance.Increment();
      }
    
      function RemoveGuest() {
        // Remove a guest
        this.counterInstance.Decrement();
      }
    }
    


    생성자에서 UserCount의 새 인스턴스를 만드는 대신 두 클래스 모두 GetInstance()를 대신 호출합니다. 즉, 하나의 클래스만 새 인스턴스를 만든 다음 해당 인스턴스가 두 클래스와 공유됩니다.

    결론



    싱글톤 디자인 패턴은 액세스 한정자를 사용하여 클래스의 인스턴스 생성을 제한하여 다른 클래스가 인스턴스를 얻을 수만 있지만 마음대로 새 인스턴스를 직접 생성할 수 없는 전체 애플리케이션 전체에 걸쳐 클래스의 전역 인스턴스를 가질 수 있도록 합니다. 내가 사용한 예제는 매우 간단하지만 일반적으로 데이터베이스 연결과 같은 리소스에 사용됩니다. 일반적으로 데이터베이스에 연결할 때마다 새 연결을 만드는 대신 한 번 연결을 만든 다음 모든 곳에서 사용해야 하기 때문입니다.

    Markus SpiskeUnsplash의 사진

    좋은 웹페이지 즐겨찾기