C#

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

Minius 2023. 2. 12. 00:59
반응형

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

디자인 패턴은 소프트웨어 개발의 근본적인 측면이며 개발자가 직면하는 일반적인 문제에 대한 입증된 솔루션 역할을 합니다. 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#에서 구현하는 방법을 이해함으로써 개발자는 보다 체계적이고 효율적이며 유지 관리 가능한 코드를 작성할 수 있습니다. 이제 막 시작했든 숙련된 개발자든 상관없이 디자인 패턴은 소프트웨어 개발에 유용한 도구라고 합니다.