0

I fail to find an answer so far, probably just lacking the appropriate keywords to search for.

I want to implement an Observer Pattern in C#, so any Observer object can subscribe to a Subject object and then receives all its notifications. Then it decides based on the Notification type whether it's important or not.

    public class Subject
{
    private List<Observer> observers;

    public void AttachObserver(Observer Observer)
    {
        this.observers.Add(Observer);
    }
    public void DetachObserver(Observer Observer)
    {
        this.observers.Remove(Observer);
    }
    public void NotifyObservers(CommonNotification Notification) // who we are, what kind of notification, bla bla
    {
        foreach(Observer Observer in observers)
        {
            Observer.OnNotify(Notification);
        }
    }
}

public class Observer
{
    public abstract void OnNotify(CommonNotification Notification);
}

So any object wanting to subscribe to a Subject needs to be an inheritance of the Observer class. But how to do that? My MainForm is based on Form. If I replace the Observer class with a general object it won't implement an OnNotify() event.

What's the point I am missing here? I know I should properly implement it using Event handlers but in order to learn how basic design patterns work I rather implement things myself first.

user2987352
  • 3
  • 1
  • 2

4 Answers4

0

you can use Interface instead of abstract class like this

public Interface IObserver
{
    public void OnNotify(CommonNotification Notification);
}

....

public class MyForm:Form, IObserver {
....
}
Grundy
  • 13,060
  • 3
  • 33
  • 51
0

You should replace your Observer class with an Interface:

public Interface IObserver
{
    public void OnNotify(CommonNotification Notification);
}

Then your mainform (or anything else) can implement IObserver

auburg
  • 1,184
  • 1
  • 10
  • 16
0

You can implement it very easily using event. I am giving a sample code -

public class MyForm : Form
{
    public event Action btn1Clicked;
    private void button1_Click(object sender, EventArgs e)
    {
        btn1Clicked();
    }
}

public abstract class AbsObserver
{
    protected MyForm Form;
    public AbsObserver(Subject subject)
    {
        subject.Attach(OnNotify);
        Form = new MyForm();
        Form.btn1Clicked += Form_btn1Clicked;
    }

    void Form_btn1Clicked()
    {
        Console.WriteLine("Do button click task");
    }

    public abstract void OnNotify();
}

public class Observer1 : AbsObserver
{
    public Observer1(Subject subject)
        : base(subject)
    {
    }

    public override void OnNotify()
    {
        Console.WriteLine("observer1 notified");
    }
}
public class Observer2 : AbsObserver
{
    public Observer2(Subject subject)
        : base(subject)
    {
    }

    public override void OnNotify()
    {
        Console.WriteLine("observer2 notified");
    }
}
public class Subject
{
    private event Action Notify;

    public void Attach(Action a)
    {
        Notify += a;
    }

    private void NotifyAll()
    {
        Notify();
    }
}

Here forms are not observers. The observers have the object of form and all form related issues are handled by the observers. This is kind of composting.

Hossain Muctadir
  • 3,410
  • 1
  • 16
  • 32
0

Short Answer: look at first answer to this question: Super-simple example of C# observer/observable with delegates

I understand you wanting to try and implement it yourself but delegates and events are really the natural fit here (and are in fact an implemention of the observer pattern built into c#).

If still want to do it yourself I would recommend using interfaces instead of abstract/concrete classes.

public interface ISubject
{
    void AttachObserver(IObserver observer);
    void DetachObserver(IObserver observer);

    void NotifyObservers(CommonNotification Notification);
}

public interface IObserver
{
    void OnNotify(CommonNotification Notification);
}

Your form could then implement IObserver (or ISubject or both!!).

public class MyForm : Form, IObserver
{
...
}
Community
  • 1
  • 1
Hans Løken
  • 407
  • 1
  • 5
  • 15