c#

C# 디자인 패턴 – Singleton, Factory, Observer 사용법

개발에대해 2025. 9. 18. 17:01
반응형

 

C# 디자인 패턴 – Singleton, Factory, Observer 사용법

C#에서 디자인 패턴(Design Pattern)은 소프트웨어 설계 문제를 효율적으로 해결하기 위한 재사용 가능한 코드 구조입니다.

실무 프로젝트에서는 객체 생성, 이벤트 처리, 모듈 간 결합도를 낮추는 데 많이 활용됩니다.

 

이번 글에서는 싱글톤(Singleton), 팩토리(Factory), 옵저버(Observer) 패턴을 예제 중심으로 살펴보겠습니다.

 

1. 싱글톤 패턴(Singleton)

싱글톤 패턴은 애플리케이션 내에서 클래스의 인스턴스를 하나만 생성하고, 어디서든 접근할 수 있도록 보장합니다.

주로 설정 관리, 로그 관리, DB 연결 객체 등에 활용됩니다.


public class Logger {
    private static Logger _instance;
    private static readonly object _lock = new object();

    // 생성자 private
    private Logger() { }

    public static Logger Instance {
        get {
            lock(_lock) {
                if (_instance == null) _instance = new Logger();
                return _instance;
            }
        }
    }

    public void Log(string message) {
        Console.WriteLine("[LOG] " + message);
    }
}

// 사용 예제
Logger.Instance.Log("애플리케이션 시작");
  

 

 

2. 팩토리 패턴(Factory)

팩토리 패턴은 객체 생성 로직을 분리하여, 클라이언트 코드가 직접 생성하지 않고도 객체를 얻을 수 있도록 합니다.

새로운 객체 유형이 추가될 때도 코드 변경 최소화가 가능합니다.


// 제품 인터페이스
public interface IShape {
    void Draw();
}

public class Circle : IShape {
    public void Draw() => Console.WriteLine("원 그리기");
}

public class Rectangle : IShape {
    public void Draw() => Console.WriteLine("사각형 그리기");
}

// 팩토리 클래스
public class ShapeFactory {
    public static IShape CreateShape(string type) {
        return type.ToLower() switch {
            "circle" => new Circle(),
            "rectangle" => new Rectangle(),
            _ => throw new ArgumentException("알 수 없는 타입")
        };
    }
}

// 사용 예제
IShape shape1 = ShapeFactory.CreateShape("circle");
shape1.Draw(); // 출력: 원 그리기

IShape shape2 = ShapeFactory.CreateShape("rectangle");
shape2.Draw(); // 출력: 사각형 그리기
  

 

 

3. 옵저버 패턴(Observer)

옵저버 패턴은 한 객체의 상태 변화가 있을 때 관련된 다른 객체들에 자동 통보하는 방식입니다.

이벤트 처리, 데이터 변경 알림, UI 갱신 등에 자주 활용됩니다.


// 주제 클래스
public class Subject {
    public event Action<string> OnStateChanged;

    public void ChangeState(string state) {
        OnStateChanged?.Invoke(state);
    }
}

// 옵저버 클래스
public class Observer {
    private string _name;
    public Observer(string name) { _name = name; }

    public void Update(string state) {
        Console.WriteLine($"{_name}가 상태 변경 알림 받음: {state}");
    }
}

// 사용 예제
var subject = new Subject();
var observer1 = new Observer("옵저버1");
var observer2 = new Observer("옵저버2");

subject.OnStateChanged += observer1.Update;
subject.OnStateChanged += observer2.Update;

subject.ChangeState("상태1"); 
// 옵저버1가 상태 변경 알림 받음: 상태1
// 옵저버2가 상태 변경 알림 받음: 상태1
 

4. 실무 활용 팁

  • 싱글톤 : 전역 설정, 로깅, DB 연결 관리에 활용
  • 팩토리 : 객체 생성 로직 분리 → 코드 변경 최소화, 신규 객체 타입 추가 용이
  • 옵저버 : UI 갱신, 이벤트 처리, 상태 변화 알림에 최적화
  • 유지보수성 고려 : 패턴을 남용하면 오히려 코드 복잡도 증가, 목적에 맞게 선택
  • 실무 조합 : 싱글톤 + 옵저버 → 전역 상태 관리와 이벤트 통합 가능

 

마무리

C#에서 디자인 패턴은 효율적인 객체 생성, 모듈 간 결합도 감소, 코드 재사용성 향상에 필수적입니다.

이번 글에서는 Singleton, Factory, Observer 패턴을 살펴보고 실무 예제를 통해 구현 방법과 활용법을 정리했습니다.

실제 프로젝트에서는 상황에 맞게 패턴을 적절히 조합하면 유지보수성과 확장성을 크게 높일 수 있습니다.

반응형