Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/292.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 松散耦合通知与事件_C#_Events_Publish Subscribe_Observer Pattern - Fatal编程技术网

C# 松散耦合通知与事件

C# 松散耦合通知与事件,c#,events,publish-subscribe,observer-pattern,C#,Events,Publish Subscribe,Observer Pattern,我编写了一个通知管理器,对象可以订阅特定的消息类型,为管理器提供回调。然后通过通知管理器的发布通知对象。它看起来像这样: [TestMethod] [TestCategory("Runtime.Game - NotificationManager")] public void Publish_invokes_callbacks() { // Arrange bool callbackCalled = false; string messageContent = "Test

我编写了一个通知管理器,对象可以订阅特定的消息类型,为管理器提供回调。然后通过通知管理器的发布通知对象。它看起来像这样:

[TestMethod]
[TestCategory("Runtime.Game - NotificationManager")]
public void Publish_invokes_callbacks()
{
    // Arrange
    bool callbackCalled = false;
    string messageContent = "Test";
    INotificationCenter notificationCenter = new NotificationManager();
    ISubscription subscription = notificationCenter.Subscribe<ShoutMessage>(
        (msg, sub) => callback = msg.Content == messageContent);

    // Act
    notificationCenter.Publish(new ShoutMessage(messageContent));
    subscription.Unsubscribe();

    // Assert
    Assert.IsTrue(callbackCalled, "The subscriber did not have its callback invoked.");
}
通知管理器的优点在于,我可以通过让所有需要对事件做出反应的对象使用NotificationManager来订阅这些事件,从而确定事物的通信方式。这有什么坏处吗?这也让我感觉更安全,因为我可以从NotificationManager singleton取消订阅,而不是在处理对象之前尝试确保取消注册我的事件处理程序。我可以快速进行空值检查,如果
IPlayer
为空,只需取消我持有的订阅即可

NotificationManager还支持谓词,因此我只能处理适用于对象实际需要查看的内容的消息。例如,只处理与接收聊天信息的角色在同一房间的玩家发送的聊天信息

ISubscription subscription = notificationCenter.Subscribe<ShoutMessage>(
    (msg, sub) => { /* ... Do stuff .. */ sub.Unsubscribe(); },
    msg => ((DefaultPlayer)msg.Sender).CurrentRoom == this.CurrentRoom);
ISubscription subscription=notificationCenter.subscription(
(msg,sub)=>{/*…做事..*/sub.Unsubscribe();},
msg=>((DefaultPlayer)msg.Sender.CurrentRoom==此.CurrentRoom);
你们认为使用pub/sub构建整个应用程序比仅仅使用eventing有什么缺点吗?它们都有使用强引用订阅对象的相同问题。我认为调试pub/sub常常很困难,因为调用堆栈太多了

我所看到的两者之间唯一的另一个区别是,通过让所有内容仅通过
NotificationManager
订阅,而不是通过单个对象订阅,两者之间的耦合稍微松散一些


你们有过酒吧/酒吧vs活动的经验吗?我不是在问哪个更好。我想在这里谈谈你对他们两人的经历以及结果如何。

这里有一个问题可能会对你有所帮助。您的NotificationManager是否需要在其运行的进程之外发送消息?例如,它是否会成为某个托管服务?如果是这样的话,使用委托作为回调可能会是一个大问题,因为需要跨线路序列化数据。使用事件,尤其是使用类型化eventarg类的事件的一个重要原因是,它们可以以允许序列化/反序列化它们的实例的方式构造。如果您的意思是我的服务器,让进程外的客户端订阅消息,服务器必须发布到-则否。服务器(telnet服务器)将接收传入的套接字通信(来自telnet客户端)并将数据推回;但是,实际的发布/订阅内容都是服务器工作方式的内部内容,不会暴露在进程之外。
ISubscription subscription = notificationCenter.Subscribe<ShoutMessage>(
    (msg, sub) => { /* ... Do stuff .. */ sub.Unsubscribe(); },
    msg => ((DefaultPlayer)msg.Sender).CurrentRoom == this.CurrentRoom);