我所要做的就是实现观察者模式。
所以,我提出了这个解决方案:
我们有一个PoliceHeadQuarters,其主要工作是向所有订阅者发送通知。考虑到DSP,Inspector和SubInspector类订阅了PoliceHeadQuarters。
使用我写的事件和代表
public class HeadQuarters
{
public delegate void NewDelegate(object sender, EventArgs e);
public event EventHandler NewEvent;
public void RaiseANotification()
{
var handler = this.NewEvent;
if (handler != null)
{
handler(this, new EventArgs());
}
}
}
public class SubInspector
{
public void Listen(object sender, EventArgs e)
{
MessageBox.Show(string.Format("Event Notification received by sender = {0} with eventArguments = {1}", sender, e.ToString()));
}
}
public class Inspector
{
public void Listen(object sender, EventArgs e)
{
MessageBox.Show(string.Format("Event Notification received by sender = {0} with eventArguments = {1}", sender, e.ToString()));
}
}
这就是我调用它的方式
var headQuarters = new HeadQuarters();
var SubInspector = new SubInspector();
var Inspector = new Inspector();
headQuarters.NewEvent += Inspector.Listen;
headQuarters.NewEvent += SubInspector.Listen;
headQuarters.RaiseANotification();
因此,无论何时调用函数RaiseANotification(),Inspector和SubInspector类都会收到通知。
似乎DotNet Framework 4,4.5支持一种名为IObserver和IObservable的新方式。
在上述场景中,任何人都可以使用IObservable和IObserver模式给我一个超级简单的例子吗?我用Google搜索,发现互联网上的可用示例过于臃肿且难以理解。
我的想法:(可能我觉得这是错的)
class DSP : IObserver //since it observes the headquarters ?
class PoliceHeadQuarters: IObservable // since here's where we send the notifications ?
提前致谢。
编辑:有人还说过,对于IObservable @,MSDN文档也是不正确的 IObservable vs Plain Events or Why Should I use IObservable?答案 0 :(得分:28)
以下是适合您的框架的MSDN示例的修改:
public struct Message
{
string text;
public Message(string newText)
{
this.text = newText;
}
public string Text
{
get
{
return this.text;
}
}
}
public class Headquarters : IObservable<Message>
{
public Headquarters()
{
observers = new List<IObserver<Message>>();
}
private List<IObserver<Message>> observers;
public IDisposable Subscribe(IObserver<Message> observer)
{
if (!observers.Contains(observer))
observers.Add(observer);
return new Unsubscriber(observers, observer);
}
private class Unsubscriber : IDisposable
{
private List<IObserver<Message>> _observers;
private IObserver<Message> _observer;
public Unsubscriber(List<IObserver<Message>> observers, IObserver<Message> observer)
{
this._observers = observers;
this._observer = observer;
}
public void Dispose()
{
if (_observer != null && _observers.Contains(_observer))
_observers.Remove(_observer);
}
}
public void SendMessage(Nullable<Message> loc)
{
foreach (var observer in observers)
{
if (!loc.HasValue)
observer.OnError(new MessageUnknownException());
else
observer.OnNext(loc.Value);
}
}
public void EndTransmission()
{
foreach (var observer in observers.ToArray())
if (observers.Contains(observer))
observer.OnCompleted();
observers.Clear();
}
}
public class MessageUnknownException : Exception
{
internal MessageUnknownException()
{
}
}
public class Inspector : IObserver<Message>
{
private IDisposable unsubscriber;
private string instName;
public Inspector(string name)
{
this.instName = name;
}
public string Name
{
get
{
return this.instName;
}
}
public virtual void Subscribe(IObservable<Message> provider)
{
if (provider != null)
unsubscriber = provider.Subscribe(this);
}
public virtual void OnCompleted()
{
Console.WriteLine("The headquarters has completed transmitting data to {0}.", this.Name);
this.Unsubscribe();
}
public virtual void OnError(Exception e)
{
Console.WriteLine("{0}: Cannot get message from headquarters.", this.Name);
}
public virtual void OnNext(Message value)
{
Console.WriteLine("{1}: Message I got from headquarters: {0}", value.Text, this.Name);
}
public virtual void Unsubscribe()
{
unsubscriber.Dispose();
}
}
public class Program
{
public static void Main(string[] args)
{
Inspector inspector1 = new Inspector("Greg Lestrade");
Inspector inspector2 = new Inspector("Sherlock Holmes");
Headquarters headquarters = new Headquarters();
inspector1.Subscribe(headquarters);
inspector2.Subscribe(headquarters);
headquarters.SendMessage(new Message("Catch Moriarty!"));
headquarters.EndTransmission();
Console.ReadKey();
}
}
答案 1 :(得分:16)
另一个建议 - 您可能希望考虑使用IObservable
将反应扩展库用于任何代码。 nuget包是Rx-Main,它的主页在这里:http://msdn.microsoft.com/en-us/data/gg577609.aspx
这将为您节省大量的样板代码。这是一个非常简单的例子:
var hq = new Subject<string>();
var inspectorSubscription = hq.Subscribe(
m => Console.WriteLine("Inspector received: " + m));
var subInspectorSubscription = hq.Subscribe(
m => Console.WriteLine("Sub Inspector received: " + m));
hq.OnNext("Catch Moriarty!");
将输出:
Inspector received: Catch Moriarty!
Sub Inspector received: Catch Moriarty!
Reactive Extensions是一个很大的主题,也是一个非常强大的库 - 值得研究。我推荐上面链接的动手实验室。
您可能希望在Inspector中嵌入这些订阅,SubInspector immplementatinos以更密切地反映您的代码。但希望这能让您深入了解使用Rx可以做些什么。