【发布时间】:2023-03-28 08:15:01
【问题描述】:
我正在尝试找出将状态更改分配到构成应用程序的多个表单的最佳方法。
在我的场景中,我有许多由我的应用程序监控的硬件设备。作为示例,设备之一是GPS设备。来自这些设备的数据进入,然后信息存储在一个大状态对象中。例如,输入的 GPS 位置与应用程序可用的当前位置和历史位置一起存储。
该应用程序有许多不同的表单和窗口可供用户使用。例如,GPS 有一个显示头顶可见卫星的表格,还有一个显示信噪比的表格和另一个显示 GPS 轨迹随时间变化的表格。
我考虑过的一个解决方案是在我的状态对象上使用类似于观察者模式的东西。新表单订阅状态对象,然后在状态对象更改时接收推送通知(新的 GPS 位置强制推送到表单,然后表单重新绘制并重新更新自己的状态)。
IObserver = interface
procedure Update;
end;
IObservable = interface
procedure Subscribe(Observer : IObserver);
end;
TObserverForm = class(TForm, IObserver)
// ....
procedure Update;
begin
// State has changed, update
end;
end;
TApplicationState = class(IObservable);
private
FObservers : TList<IObserver>;
FPosition : TPoint;
public
procedure Subscribe(Observer : IObserver);
begin
FObservers.Add(Observer);
end;
procedure PushUpdate;
begin
foreach Observer in Observers
Observer.Update;
end;
property Position : TPoint read GetPosition write SetPosition;
procedure SetPosition(Pos : TPoint);
begin
FPosition : Pos;
// Notify all observers
Self.PushUpdate;
end;
end;
以上是我正在考虑的粗略模型。这依赖于在应用程序生命周期期间创建的每个 TObserverForm 上调用 Subscribe 的状态(并在它们被销毁时取消订阅)。
我真的看不出这有什么缺点。此解决方案可以进行一些调整,以便 TObserverForms 仅更新并对某些类型的推送更新做出反应。
这里是否缺少一些基本的东西?这个常见问题是否有更合乎逻辑/更简单的解决方案?
【问题讨论】:
-
观察者模式非常简单。如果它符合您的需求(听起来确实如此),请使用它。我认为这个问题是基于意见的,因为对于大多数问题有不止一种可能的方法。我投票决定关闭,但如果您在实施过程中偶然发现一些具体问题,请随时提出单独的问题。
-
@RenéHoffmann 感谢您的回复。它似乎确实符合我的需求,但我主要想知道其他人是如何复制这个的,以及是否有比这更好的方法。不过我明白你在说什么,谢谢。
-
FWIW - 我喜欢它。我可能会产生订阅特定数据类型而不是每种数据类型的想法。此外,我已经通过订阅完成了一段时间 - 如果观察者想要继续接收数据,则需要重新订阅。这避免了订阅者在关闭之前没有取消订阅的问题,只要状态正在运行,就不会发送数据(我的是 UDP 传输,所以无连接)。
-
也许你的问题更适合programmers.stackexchange.com,在那里可以提出更抽象的问题。
-
@RenéHoffmann 在引用其他网站时,指出cross-posting is frowned upon 通常会有所帮助
标签: forms delphi observer-pattern