Re: Consuming your own events.
Sebastien Lambla <[email protected]> Wed, 30 Jan 2008 11:15:47 +0000
| Newsgroups | gmane.comp.windows.devel.dotnet.clr |
|---|---|
| Message-ID | <[email protected]> |
> In this case the guidelines are right and sadly you are wrong =) I think everybody's wrong and it's my job to try and find patterns that will compensate for the misuse and disastrous state of the OnXxx anti-pattern. > and even worse it is only your guideline =( I've applied this pattern to a few projects that have been worked on by quite a few people, so technically even though it's my guideline it has a viral property. I know some of my clients continue using it now. But the fact that it's not a MS recommendation is quite irrelevant to the technical merits discussion. > 1. the protected virtual OnTheEvent( ... ) shall only EVER be used to > raise the event; no other logic. > If you implement other logic here, in a class designed for inheritance > you are in trouble. You see, most frameworks get this wrong. As was pointed earlier, some OnXxx call the event, some rely on calling the base class, some objects are in an undeterministic state if you attach to your own events, which forces you to use OnXxx. When you start, like in WPF, using different property stores for your events, the problem becomes even worse (and it's that problem that has triggered my move to this new pattern). The theory is nice, and you're probably right. But OnXxx is badly broken, the guideline has never been applied properly, even within Microsoft. And I'll state again that it's lacking the semantics provided by Cancelable events, two stepped event raising, RaiseXxx and HandleXxx methods. > 2. Cancelable events are just a hack, remember that an event is a > multicast delegate. Using OnTheEvent( ... ) you can control if the > event is raised. Sure you can get the invocation list and call the > clients one at a time; but how do you handle the case where a client > further down the list cancels the operation??? Do you compensate for > it??? If so how??? Cancelable events can either work in a voting mechanism or simply called in a chain. The way you choose to invoke the observers and interpret the results are up to you. That said, cancelling the event before it's raised as I proposed, and cancelling the action in the Xxxing event in a voting mechanism is not what I would consider a hack. I think it carries the semantic very explicitly. OnXxx doesn't. Do I compensate for it? Well if one of the observers wnat to cancel an action when the event is raised, or if the child class decides to cancel the event before it's raised, I don't need to compensate, being able to have someone cancel the operation *is* the point of it. As for events being multicast delegates, at the end of the day they're all pointers to a vtable. I don't think that has much relevance. The use of events is to provide observer semantics. They happen to be leveraging multicast delegates, but that doesn't change the semantics. > > 3. OnTheEvent( ... ) notation or HandleTheEvent( ... ) is internal > stuff, if they show up publicly then someone broke the encapsulation > principle. The OnXxx i'm talking about is a protected method so none of this is publicly showing. It's a contract with your inheritors. I say that OnXxx is a poor contract as it's used to raise events, attach to events, or implement operations when an event happens to compensate for ordering issues. The contract is poor and I think it should be ignored altogether to clean up the process. > 4. Using base classes are always pretty brittle; It is just simply very > very very hard to design and implement a class correctly for > inheritance. That I agree with. But if you rely too much on documentation for the behaviour that needs to be followed by your inheritors, you're putting yourself into a situation where you have a fairly weak contract. -- SerialSeb =================================== This list is hosted by DevelopMentorĀ® http://www.develop.com View archives and manage your subscription(s) at http://discuss.develop.com