Events versus overridable methods?
Can anyone provide me 开发者_Go百科with general guidelines as to when I should use overridable methods such as "OnMyEvent", and when I should use events such as "MyEvent" in C#?
Are there any general design principles that can define what to use?
The two features are vaguely similar (both are designed to do some form of dynamic dispatch), but are not directly comparable.
Events are to notify other objects that an object has come to some sort of state transition. It is a language feature that embodies the Observer Design Pattern. This can be useful in a lot of cases, but is not always useful or desirable. It is a tool to get specific jobs done.
Virtual functions are used to create Object Oriented Polymorphism. They are a basic building block of nearly every Design Pattern, and a lot of object oriented design.
To try to compare them, I'll assume you're trying to implement some form of observer pattern with either feature. With that restriction in place, there is still no simple rule you can fall back on to decide which you should use. Instead, you'll have to ask yourself questions like:
- Who caused it: Will the action that triggers your state transition occur internally, or will it be externally triggered?
If it is triggered internally, you could use an event or a virtual method. If it is triggered externally, you must use a virtual method.
- Who cares about it: Should the class that defines the state handle the consequences of the state transition, or should an external class handle it?
If the class that owns the state should handle the transition, then it should be a virtual method. If a separate class should react to the transition, it should be an event.
- How many handlers do I need: Do you always need one handler to react to the state transition, or do you need many?
If you need one, then either using a virtual method or an event could be acceptable. If you need many, then it will be much easier to use an event.
- Do I know which handler I want at compile time: Do I bind to a single well-known handler, or do I bind to unknown handlers, possibly changing over time?
If you need your handlers to change, you must use events. If you only have a single handler that is known at compile time, you could use a virtual method.
- How coupled should my code be: Does your handler code belong to a derived class of your original type, or does it belong somewhere else?
If it belongs in a derived class, you need a virtual method. If it belongs elsewhere, then you need an event.
As you can see, the answers will greatly depend on your specific problem domain and object architecture. Good design isn't something that magically falls into your lap via some check list. You have to think about it, a lot :)
Edit:
It may not be directly applicable to C# events, but it may be useful to take example from existing work. Here is a brief article I just found (while answering a different question) on design alternatives in Java for eventing patterns: http://csis.pace.edu/~bergin/patterns/event.html
Events are great for when you have a "has a" while overrides are a lot better for situations where you have a "is a" relationship
For an example, if you have a base class animal, it is likely the case that each animal will have its own way of moving. however every animal is in some way going to want to move.
Now think of a class person that may 'have' a pet animal. in this case the Person might react to the animal moving but it wouldn't actually handle the animal moving.
精彩评论