Questions tagged «observer-pattern»

1
消费者/生产者与观察者/可观察者之间的差异
我正在设计一个包含三个部分的应用程序: 监视某些事件(文件创建,外部请求等)发生的单个线程 N个工作线程通过处理它们来响应这些事件(每个工作进程处理并消耗一个事件,并且处理可能需要花费可变的时间) 一个控制器,用于管理那些线程并执行错误处理(线程重新启动,结果记录) 尽管这是非常基本的,并且不难实现,但我想知道这样做的“正确”方法是什么(在Java的这种具体情况下,但也希望有更高的抽象答案)。我想到两种策略: 观察者/可观察者:监视线程由控制器观察。在发生事件的情况下,然后会通知控制器,并可以将新任务分配给可重用的缓存线程池中的空闲线程(如果所有线程当前都忙,请等待并将任务缓存在FIFO队列中)。工作线程实现Callable并返回结果(或布尔值)成功或返回错误,在这种情况下,控制器可以决定要执行的操作(取决于发生的错误的性质)。 生产者/消费者:监视线程与控制器(事件队列)共享一个BlockingQueue,并且控制器与所有工作器(任务队列和结果队列)共享两个。在发生事件的情况下,监视线程将任务对象放入事件队列中。控制器从事件队列中获取新任务,对其进行审阅并将其放入任务队列中。每个工作人员都在等待新任务,并从任务队列中获取/使用它们(先到先服务,由队列本身进行管理),然后将结果或错误放回到结果队列中。最后,控制器可以从结果队列中检索结果,并在出现错误的情况下采取相应的步骤。 两种方法的最终结果是相似的,但是它们都有细微的差别: 使用观察者,线程的控制是直接的,每个任务都归属于特定的新生成的工作程序。创建线程的开销可能更高,但是由于缓存了线程池,因此开销并不大。另一方面,“观察者”模式被简化为单个“观察者”模式,而不是多个观察者模式,这与其设计的目的不完全相同。 队列策略似乎更容易扩展,例如,添加多个生产者而不是一个生产者很简单,不需要任何更改。不利之处在于,即使根本不做任何工作,所有线程也将无限期运行,并且错误/结果处理看起来不像第一个解决方案那样优雅。 在这种情况下最合适的方法是什么?为什么?我发现很难在线找到该问题的答案,因为大多数示例仅处理明确的案例,例如用“观察者”案例更新许多具有新值的窗口或与多个消费者和生产者进行处理。任何输入,不胜感激。

4
哪种设计模式更适合记录?
我应该在程序中记录一些事件,但据我所知,最好将记录代码保留在程序之外,因为这与程序的实际功能无关。因此,您能否告诉我是否应该完全将其保留在代码之外,而仅使用观察者和侦听器记录事件?或者,我可以在需要记录某些内容的地方添加如下代码: MyGloriousLogger.getXXXLogger().Log(LogPlace, new LogObject(z1, z2, z3, z4, ..., z99)); 使用观察者设计模式是否会出错?我需要其他设计模式吗?还是我应该停止考虑设计模式? PS1。如果我只想使用侦听器和观察者进行登录,则肯定需要添加和改进程序的观察者和侦听器。 PS2。我当然知道有许多用于登录Java的库,并且我正在使用java.utils.logging,但是我需要有一个包装器来记录我的特殊对象。

3
观察者模式;知道*什么*改变了吗?
我创建了两个抽象类Subject和Observer,它们定义了经典的Observer模式接口。我从中派生出实现Observer模式的方法。观察者可能看起来像这样: void MyClass::Update(Subject *subject) { if(subject == myService_) { DoSomething(); } else if(subject == myOtherService_) { DoSomethingElse(); } } 很好,它告诉我谁更改了某些内容。但是,它没有告诉我发生了什么变化。有时这是可以的,因为我只是要查询主题以获取最新数据,但是其他时候我需要知道主题上发生了什么变化。我注意到在Java中,它们同时具有notifyObservers()方法和notifyObservers(Object arg)方法,以大概指定有关更改内容的详细信息。 就我而言,我需要知道是否有几个不同的动作中的一个发生在主体上,如果是特定动作,则需要知道与该动作相关的整数。 所以我的问题是: 传递通用参数的C ++方法是什么(就像Java一样)? 观察者甚至是最好的模式吗?也许某种事件系统? 更新 我找到了这篇文章,该文章讨论了如何对观察者模式进行模板化:使用模板实现主题/观察者模式。这让我想知道是否可以模板化参数。 我发现了这个关于模板参数模板化的堆栈溢出问题:基于模板的主题观察者模式-我应该使用static_cast还是dynamic_cast。但是,OP似乎有一个没有人回答的问题。 我可以做的另一件事是将Update方法更改为采用EventArg对象,如下所示: void MyClass::Update(Subject *subject, EventArg arg) { ... 然后为特定的参数数据创建EventArg的子类,然后将其投射回update方法中的特定子类。 更新2 还发现了一篇关于创建基于异步消息的c ++框架的文章;第2部分将具有主题讨论交流有关细节什么改变。 我现在正在认真考虑使用Boost.Signals。简单的时候使用我自己的观察者模式很有意义,但是模板化类型和参数开始变得复杂。我可能需要Boost.Signals2的线程安全性。 更新3 我还发现了一些关于观察者模式的有趣文章: 赫伯·萨特的观察家概论 在C ++中实现观察者模式-第1部分 实施观察者设计模式的经验(第2部分) 实施观察者设计模式的经验(第3部分) 但是,我已将实现切换为使用Boost.Signals,尽管出于我的目的可能有点blo肿,但它可以成功运行。可能有关膨胀或速度的任何问题都是无关紧要的。

2
当观察者彼此不独立时,观察者模式是否合适?
我有一个class Car具有2个属性的属性:int price和boolean inStock。它还持有List的abstract class State(空类)。可以在汽车上应用两种状态,每种状态由其自己的类表示:class Upgrade extends State和class Shipping extends State。 A Car可以容纳2个状态中的任何一个。各州有以下规则: Upgrade:加到1汽车本身适用的每个州的价格上。 Shipping:如果Shipping列表中至少有1个状态,则将inStock其设置为false。 例如,以price = 1和开头inStock = true: add Shipping s1 --> price: 1, inStock: false add Upgrade g1 --> price: 1, inStock: false add Shipping s2 --> price: 2, inStock: false add Shipping s3 --> price: …

4
.NET的IObserver <T>是否打算订阅多个IObservable?
.NET中也有IObservable和IObserver接口(也在此处和此处)。有趣的是,IObserver的具体实现并没有直接引用IObservable。它不知道订阅了谁。它只能调用取消订阅者。“请拉销以退订。” 编辑:取消订阅者实现IDisposable。我认为,采用这种方案是为了防止监听程序失效。 但是,有两件事对我来说并不完全清楚。 内部的Unsubscriber类是否提供“订阅并忘记”行为?谁(确切地说是何时)致电IDisposable.Dispose()取消订阅者?垃圾收集器(GC)不确定。 [免责声明:总体而言,与C#相比,我在C和C ++上花费的时间更多。] 如果我要向观察者K订阅可观察的L1并且观察者已经订阅了其他一些可观察的L2,应该怎么办? K.Subscribe(L1); K.Subscribe(L2); K.Unsubscribe(); L1.PublishObservation(1003); L2.PublishObservation(1004); 当我针对MSDN的示例运行此测试代码时,观察者仍然订阅L1。这在实际开发中将是特殊的。可能有3种方法可以改善此问题: 如果观察者已经有一个取消订阅者实例(即它已经订阅了),那么在订阅一个新的提供者之前,它会悄悄地取消订阅原始提供者。这种方法掩盖了一个事实,即它不再订阅原始提供程序,这以后可能会感到惊讶。 如果观察者已经具有取消订阅者实例,则将引发异常。行为规范的调用代码必须显式取消订阅观察者。 观察者订阅了多个提供者。这是最吸引人的选项,但是可以使用IObservable和IObserver来实现吗?让我们来看看。观察者可以保留一个非订户对象列表:每个源一个。不幸的是,IObserver.OnComplete()没有提供回发给提供者的参考。因此,具有多个提供程序的IObserver实现将无法确定要取消订阅的提供程序。 .NET的IObserver是否打算订阅多个IObservable? 教科书对观察者模式的定义是否要求一个观察者必须能够订阅多个提供者?还是可选的并且依赖于实现?

5
与观察者模式相比,委托模式有什么优势?
在委托模式中,只有一个对象可以直接侦听另一对象的事件。在观察者模式中,任意数量的对象都可以侦听特定对象的事件。当设计一个需要通知其他对象事件的类时,为什么要在观察者模式上使用委托模式?我认为观察者模式更加灵活。您现在可能只有一个观察者,但是将来的设计可能需要多个观察者。

2
通过HTTP和TCP / IP的观察者模式(服务器-客户端)
我有一台服务器和许多客户端(大约50个客户端),它们基于Web应用程序连接到该服务器,该Web应用程序当然基于HTTP协议,而HTTP协议又使用TCP / IP(如果我输入错了,请纠正我,原因是我并不是很擅长联网)。 问题是,我应该开发一种警报机制,其中,当有人提交带有危险值的表单时,经理(也通过同一Web应用程序连接的经理)应该在他的屏幕上收到警报弹出窗口,几乎是真实的时间(即时)。 但是,由于HTTP协议是无状态的,所以我有点不解。我不知道该如何实施。 解决方案之一可能是将JavaScript与setInterval()函数一起使用,以每秒从服务器提取数据。但这对我来说有点脏,而且不专业。 你们有实现另一种解决方案的想法吗?
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.