PDA

View Full Version : Programming to interfaces


rawmantick
12-25-2008, 02:38 PM
I have more a trouble of thinking how to make it "regular" rather than how to make it work.

As you, it's recommended among almost all the experianced developers to program to interfaces.

Let's just look at an example. I have two interfaces: IView and IItemRenderer. IItemRenderer is an interface for single data object visualization. IView is like some some of container for item renderers, and it has methods like:
addItemRenderer(rend:IItemRenderer)
removeItemRenderer(rend:IItemRenderer).

Everything looks good for now... We just implement those interface with exact classes and things go well.

My trouble starts when I have to deal with item renderers as not just instances of IItemRenderer, but as for example instances of IEventDispatcher. Say I just want to hang some event listener to freshly added renderer.

So what do I do? Pass an exact renderer as an argument to view's addRenderer(). Argument's exact type is some display object. But in fact, I should deal with it as with IItemRenderer. How is that? I cast the argument to some type, for example Sprite. Eh... This is the problem. Since IMO casting is a very bad thing in this case.

So, what are the ways to go:

1. Just cast it implying on the fact, that it is an IEventDispatcher.

2. Let the IItemRenderer extend IEventDispatcher of IUIComponent (well in a Flex case). Ehh... I think extending interfaces is a bad thing. Interface is like some atomic thing keeping one single functionality set. Yes, this one solves thew problem... but what if I need more interfaces to be mixed in? AS3 does not support multi-inheritance. Moreover sdometimes there is no interface to one or another flash class, take a look at Sprite for example. It doesn't have someth like ISprite.

3. The solution I use, but still not sure if this one is a regular one. I make some AbstractItemRenderer class, that extends UIComponent (or Sprite) and implements IItemRenderer and IUIComponent and IEventDispatcher. After that I change interface IView so for now it deals with that abstract class, not with the pure interface. This method looks the most handy to me. But is it still a programming to interfaces??? I'm not sure...

What do you guys think of it? Which one is right, and which one is wrong? Which way do you prefer, and why:)

I'd appreciate any discussion of those, who have the same trouble making their head boilng sometimes...

Sorry for my english:)

newblack
12-25-2008, 09:43 PM
your english is fine!

i've handled that problem in the exact ways that you have. i'm NEVER happy with the first solution. the 2nd is a more appropriate solution. i don't have the same issue you do with it- i have no problem extending interfaces.

ultimately my thought is that when you run into this problem, you're trying too hard to type to an interface. an interface should elegantly describe an imposed structure so that its use is completely extracted from the caller. when you get into nit-picking over whether you're treating it as an IView here or an IEventDispatcher there, you're holding structure is over-stepping its bounds in trying to simply use that interface's offering of a set, simple, extracted API. so it's ultimately not a problem with your interface or your implementation of it, but rather your use of it, i think.

i think that if you can handle your needs via inheritance, then you don't need an interface. if you need an interface to abstract an API, and if you run into the problem you're describing, you might be expecting too much from that interface.

rawmantick
12-26-2008, 07:10 AM
Thanks newblack. The more I think of it the more I realize what you've said. I want to much from interfaces. Yeah, it's awesome, if you have built your system on only interfaces. But sometimes it's almost impossible. So system built on abstract classes that implement required interfaces is a good thing either. So probably I'm still on 3'd one.

yell0wdart
12-29-2008, 03:40 PM
I think a lot of people get hung up on "programming to interfaces" because that's the verbage that a lot of books use. In fact, a lot of books I've read use that terminology when they're meaning "programming to abstractions" (abstraction meaning an interface OR an abstract class). There's a fantastic book (http://www.amazon.com/Principles-Patterns-Practices-Robert-Martin/dp/0131857258/ref=pd_bbs_sr_1?ie=UTF8&s=books&qid=1230568691&sr=8-1) I read on Agile development and OO principles that puts a very practical spin on your problem (never mind the fact that it's a C# book, the OO principles outlined still apply).

If you create an abstract class that implements the needed interfaces, then you're essentially getting the same benefit that you'd get from "programming to an interface". My thought on the issue is not to get so hung up on that term "interface" and focus more on abstractions. Using an abstract class allows you to leverage inheritance to apply the OO principle of Dependency Inversion (http://en.wikipedia.org/wiki/Dependency_inversion_principle).

I think the approach you're taking with #3 is just fine. Probably the same approach I'd take, if dealing with the same issue.