Computer >> 컴퓨터 >  >> 프로그래밍 >> C#

C# 프라이빗 생성자(Private Constructor)와 싱글톤(Singleton) 클래스 완벽 가이드

C#에서 프라이빗 생성자(private constructor)는 외부에서 객체를 직접 생성하지 못하도록 막는 특수한 생성자입니다. 주로 정적(static) 멤버만 포함하는 클래스나, 인스턴스가 하나만 존재해야 하는 싱글톤 패턴을 구현할 때 활용됩니다.

프라이빗 생성자란?

정적 멤버만 가지고 있는 클래스에는 프라이빗 생성자를 사용하는 것이 일반적입니다. 아래 예제처럼 생성자에 private 접근 제한자를 붙이면, 클래스 외부에서 new 키워드로 인스턴스를 만들 수 없습니다.

class Demo {
    // 프라이빗 생성자
    private Demo() { }

    public static int a = 10;
}

이렇게 하면 해당 클래스는 오직 정적 멤버를 통해서만 접근할 수 있으며, 불필요한 인스턴스 생성을 원천적으로 차단할 수 있습니다.

싱글톤 클래스와 프라이빗 생성자의 관계

싱글톤(Singleton) 클래스는 애플리케이션 전체에서 단 하나의 인스턴스만 존재하도록 보장하는 디자인 패턴입니다. 일반적인 메서드를 가질 수 있으며, 미리 만들어 둔 단일 인스턴스를 통해 기능을 호출합니다.

여기서 핵심 역할을 하는 것이 바로 프라이빗 생성자입니다. 생성자를 private으로 선언하면 외부 코드가 임의로 새 인스턴스를 만들 수 없으므로, 자연스럽게 다중 인스턴스 생성을 방지할 수 있습니다.

싱글톤 구현 예제

다음은 프라이빗 생성자를 활용한 기본적인 싱글톤 클래스 구조입니다.

public class Singleton {
    // 유일한 인스턴스를 저장하는 정적 변수
    static Singleton instance = null;

    // 프라이빗 생성자: 외부에서 new로 생성 불가
    private Singleton() {
    }

    // 인스턴스에 접근하는 정적 메서드
    public static Singleton GetInstance() {
        if (instance == null) {
            instance = new Singleton();
        }
        return instance;
    }
}

동작 방식 설명

  • 정적 변수(instance): 클래스의 유일한 인스턴스를 저장합니다. 처음에는 null로 초기화됩니다.
  • 프라이빗 생성자: 외부에서 new Singleton() 호출 시 컴파일 오류가 발생하여 인스턴스 중복 생성을 막습니다.
  • GetInstance() 메서드: 인스턴스가 아직 없으면 최초 한 번만 생성하고, 이후에는 항상 동일한 인스턴스를 반환합니다.

사용 시 주의사항

멀티스레드 환경에서는 두 스레드가 동시에 GetInstance()를 호출해 인스턴스가 두 번 생성될 위험이 있습니다. 이 경우 lock 문이나 Lazy<T> 타입을 사용해 스레드 안전성을 확보하는 것이 좋습니다.

public sealed class ThreadSafeSingleton {
    private static readonly Lazy<ThreadSafeSingleton> lazy =
        new Lazy<ThreadSafeSingleton>(() => new ThreadSafeSingleton());

    private ThreadSafeSingleton() { }

    public static ThreadSafeSingleton Instance => lazy.Value;
}

이처럼 프라이빗 생성자는 단순히 접근을 제한하는 것을 넘어, 인스턴스 생성 정책을 강제하는 강력한 도구입니다. 정적 유틸리티 클래스나 설정 관리, 로깅, 데이터베이스 연결 관리 등 전역적으로 하나의 객체만 필요한 상황에서 싱글톤 패턴과 함께 적극적으로 활용해 보세요.