我正在使用基于Eclipse RCP的框架,该框架受到低效事件模型的影响。具体而言,控件发出的事件通常是“级联”。例如,控件将发出COLOR_CHANGED
事件,导致父组合将事件传播给兄弟控件,而兄弟控件又决定发出自己的COLOR_CHANGED
事件(响应原始事件),导致各种连锁反应。我已经分析了应用程序引发超过100,000个事件以呈现一个简单的表单。坦率地说,我不明白它是如何溢出堆栈的。
所以,我正在寻找一种技术或设计模式来防止或减少这种级联行为。我有一些想法,但这不是一个新问题;对于面向事件的设计,必须有一个“最佳实践”。
我的想法:
ValidationFailedEvent
而不是每个人都处理的通用Event
(然后必须询问它的状态以确定事件类型)。感谢您抽出宝贵时间阅读我的问题。欢迎提出所有意见/建议。
编辑:感谢pablosaraiva,我读到了Chain-of-responsibility,现在有了以下想法:
isHandled
属性,如果设置为true,将阻止事件传播。这应该在事件的范围被理解时起作用,但如果事件不能由单个控件“处理”则无效。答案 0 :(得分:1)
多年来,我一直在玩这种方法。您可以采取的基本措施是让模型仅在实际发生变化时才发出事件。这使得模型中的每个类的模型稍微复杂一些,但这是我设法使这个范例有效的唯一方法。
例如
public void setColor(Color c)
{
setBackground(c);
notify(new ColorChangedEvent(this, c));
}
会变成
public void setColour(Color c)
{
if (!getBackground().equals(c))
{
setBackground(c);
notify(new ColorChangedEvent(this, c));
}
}
java中的标准Observable类使用'setChanged()'方法支持它。
实现这一点的一种稍微简单的方法(但恕我直言并不是那么好)是让'notify'关闭监听,直到它完成通知。也就是说,通知看起来像
private iAmNotifying;
public void notify(Event e)
{
if (!iAmNotifying)
{
iAmNotifying = true;
doTheActualNotification(e);
iAmNotifying = false;
}
}
但是这在粒度方面有一些明显的缺点,并且我在第一种方法上取得了更好的成功。