【问题标题】:Events versus overridable methods?事件与可覆盖的方法?
【发布时间】:2011-07-31 03:26:24
【问题描述】:

任何人都可以向我提供关于何时应使用可覆盖方法(如“OnMyEvent”)以及何时应使用事件(如 C# 中的“MyEvent”)的一般指导吗?

是否有任何通用设计原则可以定义使用什么?

【问题讨论】:

    标签: c# events methods overriding


    【解决方案1】:

    这两个功能有点相似(两者都旨在执行某种形式的动态调度),但不能直接比较。

    事件是为了通知其他对象一个对象已经到达某种state transition。这是体现the Observer Design Pattern 的语言特性。这在很多情况下都很有用,但并不总是有用或可取的。它是完成特定工作的工具。

    虚拟函数用于创建Object Oriented Polymorphism。它们是几乎所有设计模式和许多面向对象设计的基本构建块。

    为了比较它们,我假设您正在尝试使用任一功能实现某种形式的观察者模式。有了这个限制,你仍然没有简单的规则可以依靠来决定你应该使用哪个。相反,您必须问自己以​​下问题:

    • 谁造成的:触发状态转换的动作是在内部发生,还是在外部触发?

    如果它是内部触发的,您可以使用事件或虚拟方法。如果是外部触发,则必须使用虚方法。

    • 谁在乎:定义状态的类应该处理状态转换的后果,还是应该由外部类处理?

    如果拥有状态的类应该处理转换,那么它应该是一个虚拟方法。如果一个单独的类应该对转换做出反应,它应该是一个事件。

    • 我需要多少个处理程序:您总是需要一个处理程序来响应状态转换,还是需要很多?

    如果您需要一个,那么使用虚拟方法或事件都是可以接受的。如果你需要很多,那么使用事件会容易得多。

    • 在编译时我是否知道我想要哪个处理程序:我是绑定到单个知名处理程序,还是绑定到未知处理程序,可能会随着时间而改变?

    如果您需要更改处理程序,则必须使用事件。如果您只有一个在编译时已知的处理程序,则可以使用虚拟方法。

    • 我的代码应该如何耦合:您的处理程序代码是属于您的原始类型的派生类,还是属于其他地方?

    如果它属于派生类,则需要一个虚方法。如果它属于其他地方,那么您需要一个事件。

    如您所见,答案很大程度上取决于您的具体问题域和对象架构。好的设计并不是通过一些检查清单神奇地落入您的怀抱。您必须考虑很多:)

    编辑:

    它可能不直接适用于 C# 事件,但从现有工作中获取示例可能很有用。这是我刚刚找到的一篇简短文章(在回答不同的问题时),关于 Java 中事件模式的设计替代方案:http://csis.pace.edu/~bergin/patterns/event.html

    【讨论】:

      【解决方案2】:

      当你有一个“有”关系时,事件非常有用,而覆盖在你有一个“是”关系的情况下要好得多

      例如,如果您有一个基类动物,则很可能每种动物都有自己的移动方式。然而,每只动物都会以某种方式想要移动。

      现在想想一个可能“拥有”宠物的班级人。在这种情况下,Person 可能会对动物的移动做出反应,但它实际上不会处理动物的移动。

      【讨论】:

      • 很好的答案!我想这是有道理的!
      • 这个想法让我很感兴趣。继续你的陈述,你能否扩展你的答案,在一两个例句中使用这些短语?
      猜你喜欢
      • 2012-12-24
      • 2014-01-09
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2012-07-11
      • 1970-01-01
      相关资源
      最近更新 更多