겨울 세일!
옵서버

C#으로 작성된 옵서버

옵서버 패턴은 일부 객체들이 다른 객체들에 자신의 상태 변경에 대해 알릴 수 있는 행동 디자인 패턴입니다.

옵서버 패턴은 구독자 인터페이스를 구현하는 모든 객체에 대한 이러한 이벤트들을 구독 및 구독 취소하는 방법을 제공합니다.

복잡도:

인기도:

사용 사례들: 옵서버 패턴은 C 코드, 특히 그래픽 사용자 인터페이스 컴포넌트들에서 매우 일반적입니다. 다른 객체들과의 클래스들과 결합하지 않고 해당 객체들에서 발생하는 이벤트들에 반응하는 방법을 제공합니다.

식별: 옵서버 패턴은 들어오는 메서드들을 목록에 저장하는 구독 메서드로 초기 식별할 수 있으며, 만약 위 구독 메서드가 목록의 객체들을 순회하고 그들의 '업데이트' 메서드를 호출하면 해당 패턴은 옵서버 패턴으로 확정지을 수 있습니다.

개념적인 예시

이 예시는 옵서버 패턴의 구조를 보여주고 다음 질문에 중점을 둡니다:

  • 패턴은 어떤 클래스들로 구성되어 있나요?
  • 이 클래스들은 어떤 역할을 하나요?
  • 패턴의 요소들은 어떻게 서로 연관되어 있나요?

Program.cs: 개념적인 예시

using System;
using System.Collections.Generic;
using System.Threading;

namespace RefactoringGuru.DesignPatterns.Observer.Conceptual
{
    public interface IObserver
    {
        // Receive update from subject
        void Update(ISubject subject);
    }

    public interface ISubject
    {
        // Attach an observer to the subject.
        void Attach(IObserver observer);

        // Detach an observer from the subject.
        void Detach(IObserver observer);

        // Notify all observers about an event.
        void Notify();
    }

    // The Subject owns some important state and notifies observers when the
    // state changes.
    public class Subject : ISubject
    {
        // For the sake of simplicity, the Subject's state, essential to all
        // subscribers, is stored in this variable.
        public int State { get; set; } = -0;

        // List of subscribers. In real life, the list of subscribers can be
        // stored more comprehensively (categorized by event type, etc.).
        private List<IObserver> _observers = new List<IObserver>();

        // The subscription management methods.
        public void Attach(IObserver observer)
        {
            Console.WriteLine("Subject: Attached an observer.");
            this._observers.Add(observer);
        }

        public void Detach(IObserver observer)
        {
            this._observers.Remove(observer);
            Console.WriteLine("Subject: Detached an observer.");
        }

        // Trigger an update in each subscriber.
        public void Notify()
        {
            Console.WriteLine("Subject: Notifying observers...");

            foreach (var observer in _observers)
            {
                observer.Update(this);
            }
        }

        // Usually, the subscription logic is only a fraction of what a Subject
        // can really do. Subjects commonly hold some important business logic,
        // that triggers a notification method whenever something important is
        // about to happen (or after it).
        public void SomeBusinessLogic()
        {
            Console.WriteLine("\nSubject: I'm doing something important.");
            this.State = new Random().Next(0, 10);

            Thread.Sleep(15);

            Console.WriteLine("Subject: My state has just changed to: " + this.State);
            this.Notify();
        }
    }

    // Concrete Observers react to the updates issued by the Subject they had
    // been attached to.
    class ConcreteObserverA : IObserver
    {
        public void Update(ISubject subject)
        {            
            if ((subject as Subject).State < 3)
            {
                Console.WriteLine("ConcreteObserverA: Reacted to the event.");
            }
        }
    }

    class ConcreteObserverB : IObserver
    {
        public void Update(ISubject subject)
        {
            if ((subject as Subject).State == 0 || (subject as Subject).State >= 2)
            {
                Console.WriteLine("ConcreteObserverB: Reacted to the event.");
            }
        }
    }
    
    class Program
    {
        static void Main(string[] args)
        {
            // The client code.
            var subject = new Subject();
            var observerA = new ConcreteObserverA();
            subject.Attach(observerA);

            var observerB = new ConcreteObserverB();
            subject.Attach(observerB);

            subject.SomeBusinessLogic();
            subject.SomeBusinessLogic();

            subject.Detach(observerB);

            subject.SomeBusinessLogic();
        }
    }
}

Output.txt: 실행 결과

Subject: Attached an observer.
Subject: Attached an observer.

Subject: I'm doing something important.
Subject: My state has just changed to: 2
Subject: Notifying observers...
ConcreteObserverA: Reacted to the event.
ConcreteObserverB: Reacted to the event.

Subject: I'm doing something important.
Subject: My state has just changed to: 1
Subject: Notifying observers...
ConcreteObserverA: Reacted to the event.
Subject: Detached an observer.

Subject: I'm doing something important.
Subject: My state has just changed to: 5
Subject: Notifying observers...

다른 언어로 작성된 옵서버

C++로 작성된 옵서버 Go로 작성된 옵서버 자바로 작성된 옵서버 PHP로 작성된 옵서버 파이썬으로 작성된 옵서버 루비로 작성된 옵서버 러스트로 작성된 옵서버 스위프트로 작성된 옵서버 타입스크립트로 작성된 옵서버