使用带有事件的观察者模式添加新闻订阅者
Add a news subscriber using observer pattern with events
我正在使用观察者模式通过事件从新闻通讯中添加和删除订阅者。
我不确定如何处理我正在尝试做的事情。是否可以使用事件添加订阅者?如何添加?
控制台由带有按钮的表单操作,因此当单击按钮时它将添加订阅者,当单击删除按钮时它将删除订阅者,在表单上,还有一个按钮 post 一份时事通讯,它将 post 每个订阅者的时事通讯。
这是我到目前为止设法得到的:
class Program
{
//[STAThread]
static void Main(string[] args)
{
SoftwareRevolution softrev = new Ass_3._1.SoftwareRevolution();
ConsoleOutput First = new ConsoleOutput(softrev);
softrev.Datetime = DateTime.Now.ToLongDateString() + " " + DateTime.Now.ToLongTimeString();
Application.EnableVisualStyles();
Application.SetCompatibleTextRenderingDefault(true);
Application.Run(new InputForm());
}
}
public delegate void NotifyMe(string Value);
class ConsoleOutput : IEventsObserver
{
IEventsSubject IEventsSubject;
public ConsoleOutput(IEventsSubject IEventsSubject)
{
this.IEventsSubject = IEventsSubject;
this.IEventsSubject.Notifier += new Ass_3._1.NotifyMe(UpdateNews);
}
public void UpdateNews(string info)
{
Console.WriteLine(info);
}
}
interface IEventsObserver
{
void UpdateNews(string info);
}
interface IEventsSubject
{
event NotifyMe Notifier;
}
class SoftwareRevolution : IEventsSubject
{
List<IEventsObserver> Readers = new List<IEventsObserver>();
private string datetime;
public string Datetime
{
get
{
return datetime;
}
set
{
datetime = value;
Notifier(datetime);
}
}
public event NotifyMe Notifier;
}
发布时事通讯的对象应该有一个在发布时事通讯时触发的事件。然后所有订阅该事件的订阅者都会收到它。
事件分发将在发布者 class 中没有此类列表的情况下完成。事实上,C# 中的委托实现会处理这一点,事件委托后面有一个调用列表。
通常 Publisher 不需要保留 Subscriber 对象本身的列表,如果您需要这样的列表,最好保留它在 SubscriptionManager.
中
订阅管理器,为订阅者订阅和取消订阅发布者的事件。它还可以保留订阅者列表。
例子
Newsletter
class 包含一些代表新闻通讯的字段:
public class Newsletter
{
public string Content;
}
NewsLetterPublishedEventArgs
包含有关已发布时事通讯的信息:
public class NewsletterPublishedEventArgs : EventArgs
{
public Newsletter Newsletter { get; set; }
}
Publisher
class 发布了时事通讯并在发布后引发了一个事件:
public class Publisher
{
public event EventHandler<NewsletterPublishedEventArgs> NewsLetterPublished;
public void PublishNewsLetter()
{
var newsLetter = new Newsletter() { Content = $"New publish at {DateTime.Now}" };
NewsLetterPublished?.Invoke(this,
new NewsletterPublishedEventArgs() { Newsletter = newsLetter });
}
}
Subscriber
class 有一个方法可以接收 NewsLetterPublished
通知:
public class Subscriber
{
public string Name { get; set; }
public void ReceiveNewsLetter(object sender, NewsletterPublishedEventArgs e)
{
MessageBox.Show(e.Newsletter.Content);
}
}
最后,SubscriptionManager
class 向发布者订阅和取消订阅订阅者:
public class SubscriptionManager
{
public Publisher Publisher => new Publisher();
private List<Subscriber> subscribers;
public void Subscribe(Subscriber s)
{
if (!subscribers.Contains(s))
{
subscribers.Add(s);
Publisher.NewsLetterPublished += s.ReceiveNewsLetter;
}
}
public void Unsubscribe(Subscriber s)
{
if (subscribers.Contains(s))
{
subscribers.Remove(s);
Publisher.NewsLetterPublished -= s.ReceiveNewsLetter;
}
}
}
备注
为了简单起见,我创建了一个简单的示例来演示用于学习目的的逻辑。在真实世界的示例中,您需要使用接口、通用 classes 和依赖注入。
我正在使用观察者模式通过事件从新闻通讯中添加和删除订阅者。
我不确定如何处理我正在尝试做的事情。是否可以使用事件添加订阅者?如何添加?
控制台由带有按钮的表单操作,因此当单击按钮时它将添加订阅者,当单击删除按钮时它将删除订阅者,在表单上,还有一个按钮 post 一份时事通讯,它将 post 每个订阅者的时事通讯。
这是我到目前为止设法得到的:
class Program
{
//[STAThread]
static void Main(string[] args)
{
SoftwareRevolution softrev = new Ass_3._1.SoftwareRevolution();
ConsoleOutput First = new ConsoleOutput(softrev);
softrev.Datetime = DateTime.Now.ToLongDateString() + " " + DateTime.Now.ToLongTimeString();
Application.EnableVisualStyles();
Application.SetCompatibleTextRenderingDefault(true);
Application.Run(new InputForm());
}
}
public delegate void NotifyMe(string Value);
class ConsoleOutput : IEventsObserver
{
IEventsSubject IEventsSubject;
public ConsoleOutput(IEventsSubject IEventsSubject)
{
this.IEventsSubject = IEventsSubject;
this.IEventsSubject.Notifier += new Ass_3._1.NotifyMe(UpdateNews);
}
public void UpdateNews(string info)
{
Console.WriteLine(info);
}
}
interface IEventsObserver
{
void UpdateNews(string info);
}
interface IEventsSubject
{
event NotifyMe Notifier;
}
class SoftwareRevolution : IEventsSubject
{
List<IEventsObserver> Readers = new List<IEventsObserver>();
private string datetime;
public string Datetime
{
get
{
return datetime;
}
set
{
datetime = value;
Notifier(datetime);
}
}
public event NotifyMe Notifier;
}
发布时事通讯的对象应该有一个在发布时事通讯时触发的事件。然后所有订阅该事件的订阅者都会收到它。
事件分发将在发布者 class 中没有此类列表的情况下完成。事实上,C# 中的委托实现会处理这一点,事件委托后面有一个调用列表。
通常 Publisher 不需要保留 Subscriber 对象本身的列表,如果您需要这样的列表,最好保留它在 SubscriptionManager.
中订阅管理器,为订阅者订阅和取消订阅发布者的事件。它还可以保留订阅者列表。
例子
Newsletter
class 包含一些代表新闻通讯的字段:
public class Newsletter
{
public string Content;
}
NewsLetterPublishedEventArgs
包含有关已发布时事通讯的信息:
public class NewsletterPublishedEventArgs : EventArgs
{
public Newsletter Newsletter { get; set; }
}
Publisher
class 发布了时事通讯并在发布后引发了一个事件:
public class Publisher
{
public event EventHandler<NewsletterPublishedEventArgs> NewsLetterPublished;
public void PublishNewsLetter()
{
var newsLetter = new Newsletter() { Content = $"New publish at {DateTime.Now}" };
NewsLetterPublished?.Invoke(this,
new NewsletterPublishedEventArgs() { Newsletter = newsLetter });
}
}
Subscriber
class 有一个方法可以接收 NewsLetterPublished
通知:
public class Subscriber
{
public string Name { get; set; }
public void ReceiveNewsLetter(object sender, NewsletterPublishedEventArgs e)
{
MessageBox.Show(e.Newsletter.Content);
}
}
最后,SubscriptionManager
class 向发布者订阅和取消订阅订阅者:
public class SubscriptionManager
{
public Publisher Publisher => new Publisher();
private List<Subscriber> subscribers;
public void Subscribe(Subscriber s)
{
if (!subscribers.Contains(s))
{
subscribers.Add(s);
Publisher.NewsLetterPublished += s.ReceiveNewsLetter;
}
}
public void Unsubscribe(Subscriber s)
{
if (subscribers.Contains(s))
{
subscribers.Remove(s);
Publisher.NewsLetterPublished -= s.ReceiveNewsLetter;
}
}
}
备注
为了简单起见,我创建了一个简单的示例来演示用于学习目的的逻辑。在真实世界的示例中,您需要使用接口、通用 classes 和依赖注入。