Who should be in charge of adding the observers to an event

56 Views Asked by At

I need to link three classes, Portal, WaveManager and TimeManager, so that when a condition is satisfied in Portal, TimeManager.SlowTime() and WaveManager.SpeedUpSpawn() are executed. Events seem to me the most obvious design solution, but I always doubt about who should be responsible for the addition of the observers. These are the two options I can imagine:

A. TimeManager and WaveManager add themselves as observers to the event in Portal:

Option A

B. The observer additions are made by an instance of some intermediary class:

Option B

Portal is a minor, peripheral class in the application, as is WaveManager compared to TimeManager. Even though it is not called from many places, it feels wrong to force TimeManager to know a minor class like Portal as I do in option A, just in order to be able to add itself as a listener to the event.

Option B on the other hand seems too convoluted, and it is not obvious which class in my code should be in charge of those additions. I would probably need to add ad hoc classes and functionalities for that purpose.

What is generally the approach to the addition of observers? Is it frequent or good practice to make the observers add themselves as observers? Are there other design options other than the two I proposed?

1

There are 1 best solutions below

0
StepUp On

I believe Portal is here a subject. So it looks like Portal should add/register new observers.

Let me show some example of implementation of an observer pattern via C#:

These are classes related to observer:

public interface IMyObserver
{
    public void Update(string myMessage);
}

and its concrete implementation:

public class MyObserver : IMyObserver
{
    private MySubject _mySubject;
    private string _myMessage;

    public MyObserver(MySubject mySubject)
    {
        _mySubject = mySubject;
        _mySubject.RegisterObserver(this);
    }

    public void Update(string myMessage)
    {
        _myMessage = myMessage;
        Console.WriteLine($"Observer have seen this message: {_myMessage}");
    }
}

These are classes related to subject:

public interface IMySubject
{
    public void RegisterObserver(IMyObserver o);

    public void RemoveObserver(IMyObserver o);

    public void NotifyObservers();
}

and its concrete implementation:

public class MySubject : IMySubject
{
    private List<IMyObserver> _observers;
    private string _myMessage;

    public MySubject() =>
        _observers = new List<IMyObserver>();

    public void NotifyObservers()
    {
        foreach (IMyObserver observer in _observers)
            observer.Update(_myMessage);
    }

    public void RegisterObserver(IMyObserver o) => _observers.Add(o);

    public void RemoveObserver(IMyObserver o) => _observers.Remove(o);

    public void MyMessageChanged() => NotifyObservers();

    public void SetMessage(string message)
    {
        _myMessage = message;
        MyMessageChanged();
    }
}

And then you can call the above code like this:

MySubject mySubject = new ();
MyObserver myObserver = new (mySubject);

// message from subject
mySubject.SetMessage("Hello World!");

OUTPUT:

enter image description here