C#中的观察者模式/如何使窗体成为观察者

C#中的观察者模式/如何使窗体成为观察者,c#,design-patterns,inheritance,observer-pattern,C#,Design Patterns,Inheritance,Observer Pattern,到目前为止,我没有找到答案,可能只是缺少合适的关键字来搜索 我想在C#中实现一个观察者模式,这样任何观察者对象都可以订阅Subject对象,然后接收其所有通知。然后根据通知类型决定它是否重要 public class Subject { private List<Observer> observers; public void AttachObserver(Observer Observer) { this.observers.Add

到目前为止,我没有找到答案,可能只是缺少合适的关键字来搜索

我想在C#中实现一个观察者模式,这样任何观察者对象都可以订阅Subject对象,然后接收其所有通知。然后根据通知类型决定它是否重要

    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);
}
公共类科目
{
非公开名单观察员;
public void AttachObserver(观察者)
{
this.Observer.Add(Observer);
}
公众观察员(观察员)
{
这个。观察员。移除(观察员);
}
public void notifyobserver(CommonNotification)//我们是谁,什么样的通知,等等
{
foreach(观察员中的观察员)
{
观察员通知(通知);
}
}
}
公共类观察员
{
公开摘要无效通知(CommonNotification);
}
因此,任何想要订阅主题的对象都需要是Observer类的继承。但如何做到这一点呢?我的主窗体基于窗体。如果我用常规对象替换Observer类,它将不会实现OnNotify()事件


我在这里遗漏了什么?我知道我应该使用事件处理程序正确地实现它,但为了了解基本设计模式是如何工作的,我宁愿先自己实现。

您可以使用接口而不是像这样的抽象类

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

....

public class MyForm:Form, IObserver {
....
}

应使用接口替换Observer类:

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

然后您的mainform(或其他任何东西)可以实现IObserver

您可以使用event非常轻松地实现它。我给出了一个示例代码-

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();
    }
}

这里的表格不是观察员。观察员具有形式的目的,所有与形式有关的问题都由观察员处理。这是一种堆肥。

简短回答:看看这个问题的第一个答案:

我知道您希望自己尝试并实现它,但是委托和事件在这里是很自然的(事实上是c#中内置的观察者模式的实现)

如果你还想自己做,我建议使用接口而不是抽象/具体类

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

    void NotifyObservers(CommonNotification Notification);
}

public interface IObserver
{
    void OnNotify(CommonNotification Notification);
}
然后,您的表单可以实现IObserver(或ISubject,或两者兼有!!)


使用接口而不是抽象类你读过了吗?你知道观察者模式已经完全集成到C语言中了吗?使用事件关键字。您的AttachObserver为+=,DetachObserver为-=,NotifyObserver为()。
public class MyForm : Form, IObserver
{
...
}