设计事件驱动通信的问题

时间:2009-12-18 22:13:18

标签: c# events event-handling

我在设计问题上苦苦挣扎。我在c#中制作了一个非常简单的gui系统。代码是可重用的,所以我在这里寻找最灵活的解决方案。我提出的解决方案似乎都有它们的缺点。

为简单起见,假设有三个类:控制器,按钮和客户端代码。客户端代码是使用gui系统的代码。它创建控制器并在其上调用Update()。控制器创建一组按钮实例并对它们调用Update()。按钮绘制自己并检查鼠标点击。

现在问题是我如何得到按钮被点击到客户端代码的事实?

选项1:将GetButton(字符串名称)添加到控制器类。然后,客户端代码可以订阅按钮类=>中定义的事件。 GetButton(“但是”)。MouseUpEvent + = MouseUpHandler;这样做的缺点是暴露了Button.Update(),它只能由控制器使用。

选项2:让控制器订阅所有按钮,客户端代码订阅控制器。这里的缺点是客户端代码中的解析代码更多,因为现在所有事件都通过控制器汇集,因此客户端必须检查发送每个事件的按钮。我更喜欢在初始化阶段设置事件流,就像在选项1中一样。

选项3:为每个事件向Controller添加Subscribe / Unsubscribe方法(SubscribeMouseUp(string buttonName,GUIDelegate del)等。)缺点是控制器api快速增长。

所以现在我倾向于选项1,但GetButton返回一个只声明事件的接口(IClientButton),从而隐藏了客户端的Update(),但我不确定这是否应该如何使用接口

任何见解都表示赞赏。 BAS

4 个答案:

答案 0 :(得分:0)

可能这是一个问题,因为Update()是公开的?

假设您已将按钮和控制器组织到同一名称空间中,使用internal保护是否符合您的需求?

答案 1 :(得分:0)

接口可以这样使用,INotifyPropertyChanged是一个带有1个项目的接口,这是一个事件。

使用RoutedEvents怎么办?

答案 2 :(得分:0)

有第四种,也许更受欢迎的选择。

将调度员作为注册/取消注册的中心位置。所有事件接收器都向调度程序注册回调。所有事件生成器都将其事件发送给调度程序。

它使API保持清洁,并有助于解开对象引用。

答案 3 :(得分:0)

在您的Controller中,添加两个事件 - ButtonCreatedButtonDestroyed

public event EventHandler<ClientButtonEventArgs> ButtonCreated;
public event EventHandler<ClientButtonEventArgs> ButtonDestroyed;

ClientButtonEventArgs只是EventArgs界面的IClientButton包装。

让您的客户端代码订阅这两个事件。当Controller创建一个新按钮时,让它激活ButtonCreated事件。然后,客户端代码可以在收到事件通知时订阅必要的Button事件。同样,Controller会根据需要触发ButtonDestroyed事件,允许客户端代码取消订阅Button的事件。

通过这种方式,整个序列是事件驱动的。客户端代码的创建和销毁做出反应,这似乎就是你所追求的。