본문 바로가기
C#

[C#] 디자인 패턴 in C#: Singleton, Factory, and Observer Patterns (싱글톤, 팩토리, 옵저버 패턴)

by Minius 2023. 2. 12.
반응형

이전부터 사내 선배 개발자 분들께서 어떤 부분을 싱글톤으로 바꾸었다고 몇번 말씀하셔서, 싱글톤에 대해 알아보다가 디자인 패턴을 알게 되었습니다. 알아봐도 잘 모르겠지만, 메모는 남겨둡니다.

디자인 패턴은 소프트웨어 개발의 근본적인 측면이며 개발자가 직면하는 일반적인 문제에 대한 입증된 솔루션 역할을 합니다. C#의 세계에는 모범 사례로 널리 사용되고 인정되는 몇 가지 디자인 패턴이 있습니다. 이 글에서는 C#에서 가장 인기 있는 세 가지 디자인 패턴인 Singleton, Factory 및 Observer를 살펴보겠습니다.

 

Singleton Pattern

Singleton 패턴은 인스턴스에 대한 글로벌 액세스 지점을 제공하면서 클래스에 인스턴스가 하나만 있는지 확인하는 생성 패턴입니다. 이 패턴은 코드의 어디에서나 액세스할 수 있는 클래스 인스턴스가 하나만 있는지 확인해야 할 때 유용합니다. Singleton 패턴은 클래스 생성자를 비공개로 만들고 클래스의 정적 인스턴스를 만들고 인스턴스를 반환하는 정적 메서드를 제공하여 구현됩니다.

 

싱글톤 패턴의 예)

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

    private Singleton()
    {
    }

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

            return _instance;
        }
    }
}

 

 

Factory Pattern

팩토리 패턴은 생성될 객체의 정확한 클래스를 지정하지 않고 객체를 생성하는 방법을 제공하는 생성 패턴입니다. Factory 패턴은 객체 생성을 위한 인터페이스를 정의하지만 인스턴스화할 클래스를 하위 클래스가 결정할 수 있도록 합니다. 이를 통해 슈퍼클래스에서 객체를 생성할 수 있지만 서브클래스에서 생성될 객체 유형을 변경할 수 있습니다.

 

팩토리 패턴의 예)

public interface IAnimal
{
    void Speak();
}

public class Dog : IAnimal
{
    public void Speak()
    {
        Console.WriteLine("Woof!");
    }
}

public class Cat : IAnimal
{
    public void Speak()
    {
        Console.WriteLine("Meow!");
    }
}

public class AnimalFactory
{
    public static IAnimal GetAnimal(string type)
    {
        switch (type)
        {
            case "dog":
                return new Dog();
            case "cat":
                return new Cat();
            default:
                throw new ArgumentException("Invalid animal type.");
        }
    }
}

 

Observer Pattern

관찰자 패턴은 객체가 다른 객체의 상태에 대한 변경 사항을 알릴 수 있도록 하는 동작 패턴입니다. 관찰자 패턴은 개체가 다른 개체의 변경 사항에 대한 알림을 받도록 등록할 수 있는 이벤트 기반 시스템을 구현하는 데 자주 사용됩니다. 이 패턴은 느슨하게 결합된 시스템을 만드는 데 유용합니다. 여기서 개체는 긴밀하게 결합되지 않고도 서로 통신할 수 있습니다.

 

관찰자 패턴의 예)

public class Subject
{
    private List<Observer> _observers = new List<Observer>();
    private int _state;

    public int State
    {
        get { return _state; }
        set
        {
            _state = value;
            NotifyAllObservers();
        }
    }

    public void Attach(Observer observer)
    {
        _observers.Add(observer);
    }

    public void Detach(Observer observer)
    {
        _observers.Remove(observer);
    }

    public void NotifyAllObservers()
    {
        foreach (Observer observer in _observers)
        {
            observer.Update();
        }
    }
}

public abstract class Observer
{
    protected Subject Subject;
    public abstract void Update();
}

public class ConcreteObserverA : Observer
{
    public ConcreteObserverA(Subject subject)
    {
        Subject = subject;
        Subject.Attach(this);
    }

    public override void Update()
    {
        Console.WriteLine("Observer A: Subject state is now " + Subject.State);
    }
}

public class ConcreteObserverB : Observer
{
    public ConcreteObserverB(Subject subject)
    {
        Subject = subject;
        Subject.Attach(this);
    }

    public override void Update()
    {
        Console.WriteLine("Observer B: Subject state is now " + Subject.State);
    }
}


이 글에서는 C#에서 가장 인기 있는 세 가지 디자인 패턴인 Singleton, Factory 및 Observer를 살펴보았습니다. 이러한 패턴과 이를 C#에서 구현하는 방법을 이해함으로써 개발자는 보다 체계적이고 효율적이며 유지 관리 가능한 코드를 작성할 수 있습니다. 이제 막 시작했든 숙련된 개발자든 상관없이 디자인 패턴은 소프트웨어 개발에 유용한 도구라고 합니다.

댓글