| Elizabeth Keogh ( @ 2005-04-12 15:53:00 |
An example of why IFoo as Foo's interface is evil and should be punished.
I thought this was worth reposting from the comments of my previous IFoo post.
IFoo is used because someone thought of a Foo class and created an interface to go with it. That kind of thinking doesn't lead to clean code in the first place.
Here's an example, using the IFoo interface notation:
I create a
Because of threading issues, I decide to create an
The
This is what I'm trying to avoid by cursing the use of IFoo. It's pretty easy to see that this is wrong, but in more complex code the roles can be lost amidst the functionality. What the
Call them
The reason I can come up with this example is because I actually did this (with a different naming convention that was easier to hide). I only realised my mistake when I plugged the EventQueueHandler in. I am, as a result of these thoughts, also convinced of the evils of DefaultFoo, and, in fact, of the use of "Foo" in example code. Foo is meaningless. It's a point which was made to me before and I didn't listen.
I thought this was worth reposting from the comments of my previous IFoo post.
Anybody who does not work in the conventions used by the project is undoing the team's hard the work to build a clean codebase with a common domain language. Agile methods stress common code ownership for a reason -- it's extremely hard to work on code that is a patchwork of the individual styles chosen by prima donna programmers. The worst project that I have had the misfortune to work on recently had different coding styles used within individual files! Anbody who does not work with the team in this respect should NOT BE ON THE TEAM, end of story.
IFoo is used because someone thought of a Foo class and created an interface to go with it. That kind of thinking doesn't lead to clean code in the first place.
Here's an example, using the IFoo interface notation:
I create a
Gui class and an IGui interface, so that the Gui can listen to the events from the Engine, which implements the IEngine interface.Because of threading issues, I decide to create an
EventQueueHandler, which can manage the events passed between one and the other. To enable it to talk to both it now has to implement both the IEngine and the IGui interface.The
EventQueueHandler is neither an Engine nor a Gui.This is what I'm trying to avoid by cursing the use of IFoo. It's pretty easy to see that this is wrong, but in more complex code the roles can be lost amidst the functionality. What the
EventQueueHandler's actually doing is listening to the ReportEvents fired by the Engine and the RequestEvents fired by the Gui, so it should be implementing RequestEventListener and ReportEventListener, which should also be the interfaces used by the Engine and the Gui respectively.Call them
IRequestEventListener and IReportEventListener if you absolutely have to, as per the comments on my previous IFoo post, but please consider blazing a new trail of code convention in your chosen language. If you really, truly can't allow developers to call them anything other than IGui and IEngine then you won't want me on your team anyway.The reason I can come up with this example is because I actually did this (with a different naming convention that was easier to hide). I only realised my mistake when I plugged the EventQueueHandler in. I am, as a result of these thoughts, also convinced of the evils of DefaultFoo, and, in fact, of the use of "Foo" in example code. Foo is meaningless. It's a point which was made to me before and I didn't listen.