[디자인 패턴 - C#] 옵저버 패턴

빵욱·2024년 5월 29일

C#_디자인 패턴

목록 보기
2/4

옵저버 패턴?

옵서버 패턴(observer pattern)은 객체의 상태 변화를 관찰하는 관찰자들, 즉 옵저버들의 목록을 객체에 등록하여 상태 변화가 있을 때마다 메서드 등을 통해 객체가 직접 목록의 각 옵저버에게 통지하도록 하는 디자인 패턴이다. 주로 분산 이벤트 핸들링 시스템을 구현하는 데 사용된다. 발행/구독 모델로 알려져 있기도 하다.
(출처 : 위키백과)

간단하게 설명하면 어떤 주체의 옵저버 역할을 하고 싶은 객체가 옵저버로 등록을 하면 주체에서 어떤 데이터의 변경여부를 알려주거나 또는 조회할 수 있게 해주는 디자인 패턴이라고 할수 있을 것 같다.

구현

상품이 있고 이 상품의 구매 가능여부를 상품에 대해 구독한 유저에게 알려준다고 가정하고 구현.

subject

Subject를 하고 싶은 객체들은 Subject인터페이스만 구현하면 주체 역활을 할 수 있도록 인터페이스를 만든다.

  public interface ISubject
  {
      void RegisterObserver(IObserver observer);
      void RemoveObserver(IObserver observer);
      void NotifyObservers();

  }

그리고 객체 구현

public class Product : ISubject
{
    private List<IObserver> _observers = new List<IObserver>();

    private string _productName;
    private string _productAvailability;

    public Product(string productName)
    {
        _productName = productName;
        _productAvailability = "Out of Stock";
    }

    public string ProductAvailability
    {
        get { return _productAvailability; }
        set { 
            _productAvailability = value;

            // _productAvailability의 내용이 변경될 때 옵저버들에게 변경 사실을 알림.
            NotifyObservers();
        }
    }

    public void RegisterObserver(IObserver observer)
    {
        _observers.Add(observer);
    }

    public void RemoveObserver(IObserver observer)
    {
        _observers.Remove(observer);
    }

    public void NotifyObservers()
    {
        foreach (var observer in _observers)
        {
            observer.Update(_productAvailability);
        }
    }
}

RegisterObserver 와 RemoveObserver는 옵저버를 구독, 구독 취소하는 메서드.

_observers -> 옵저버 관리 리스트.

  public string ProductAvailability
  {
      get { return _productAvailability; }
      set { 
          _productAvailability = value;

          // _productAvailability의 내용이 변경될 때 옵저버들에게 변경 사실을 알림.
          NotifyObservers();
      }
  }

이 부분에서 ProductAvailability의 내용이 변경(set)될 때 NotifyObservers() 메서드를 호출하여 등록된 옵저버들에게 변경 내용을 알려준다.

Observer

Observer 인터페이스를 구현하면 옵저버가 될 수 있도록 인터페이스를 구현.

 public interface IObserver
 {
     void Update(string availability);
 }

availability 에 대한 옵저버 인터페이스.

 public class User : IObserver
 {
     private string _userName;

     public User(string userName, ISubject product)
     {
         _userName = userName;

         // User 인스턴스를 product가 가지고 있는 옵저버 리스트에 등록.
         product.RegisterObserver(this);
     }

     public void Update(string availability)
     {
         Console.WriteLine($"안녕하세요, {_userName}님! 제품의 가용성이 변경되었습니다: {availability}");
     }
 }

IObserver를 구현한 user 객체
생성자에서 ISubject 객체를 받아 이 자기 자신을 옵저버 리스트에 추가한다.

테스트

간단하게 콘솔에서 테스트를 해본다.

 Product product = new Product("게임 콘솔");
 User user1 = new User("Kane", product);
 User user2 = new User("Big show", product);

 Console.WriteLine("처음 제품 상태: " + product.ProductAvailability);
 product.ProductAvailability = "In Stock";

 product.ProductAvailability = "close to being sold out";

실행하면 product의 ProductAvailability 가 변경될 때 user의 update 메서드가 실행되는 것을 확인할 수 있다.

처음 제품 상태: Out of Stock
안녕하세요, Kane님! 제품의 가용성이 변경되었습니다: In Stock
안녕하세요, Big show님! 제품의 가용성이 변경되었습니다: In Stock
안녕하세요, Kane님! 제품의 가용성이 변경되었습니다: close to being sold out
안녕하세요, Big show님! 제품의 가용성이 변경되었습니다: close to being sold out

다음 포스트에서는 C#에 이벤트를 활용해서 구현하는 것을 공부해보려 한다.

profile
rove drink eat

0개의 댓글