tags:

views:

115

answers:

3

OOP is about programming with interface, not the implementation. Objects are "talking" to each other using their interfaces. When interfaces are not well defined one object can know too much about the other and if you need to change implementation of your object you'll need to change your programm in different places. That's really bad, it`s all about changing things in one place and DRY principles. So my question is the following: what if make interface context. Interface context will make sure that if object provides multiple interfaces other objects will only be able to use the one they need. This will ease things and reduce possibility of errors.

Let me introduce the example: some abstract class that let us read text and write text. So it has two interfaces: reader and writer. If you are dealing with reader, all you need is reader methods. So we can remove the writer interface. In the real world you'll still see the reader part (in IDEs like Visual Studio). But what if make such a thing that would allow you to declare "I'm in the reader context" and you`ll be able to do things only related to reading and every class will show you its reader related interface. What do you think? Does it make sense? Like add-ins to Visual Studio that will hide other interfaces when set to one?

+3  A: 

Yes, that often makes sense, especially as you start to work more with Inversion of Control principles.

The easiest way to do this is to imlement the interface explicitly.

public interface IFoo
{
    void Foo();
}

public interface IBar
{
    void Bar();   
}
public class Baz : IFoo, IBar
{
    void IFoo.Foo()
    {

    }

    void IBar.Bar()
    {

    }
}

public class Program
{
    public void DoStuff()
    {
        Baz b = new Baz();
        //b.Foo(); // doesn't compile
        IFoo f = b as IFoo;
        f.Foo(); // works
        IBar bar = b as IBar;
        bar.Bar(); //now we an see that.
    }
}

The Foo method will only show up on Bar after you cast it to an IFoo.

kyoryu
Could you just instantiate 'b' as an IFoo object rather than casting it later? "IFoo b = new Bar();" I know this works in Java and Flex/ActionScript, but maybe not in the language you're using :)
bedwyr
Yup. Though usually when I've run into this pattern, it's either a factory/builder method stringing a bunch of objects together, or in the context of an IoC container. So, the consumer of the interface won't know about the other one at all, or even the raw type. It's the kind of scenario where a Foo talks to a Bar via IFoo, and a Baz talks to the Bar via IBaz. Neither of them know about the real class Bar, and Foo and Baz know nothing about each other.
kyoryu
BTW, this is in C#, which I kind of assumed given that the OP asked about Visual Studio plugins.
kyoryu
+2  A: 

Have a look around for Robert Martin's "Interface Segration Principle", as well as the rest of the SOLID principles of object oriented design.

Nerdfest
Upvoted for the principle of why this is a good idea, while I just covered the *how*.
kyoryu
Thanks for the tip, Nerdfest! Starting reading right now. I think he says exactly of my problem. But what is solution of all that? Sure if you prevent interfaces from being fat it`s ok. But not every one in every programm will prevent them from being fat. So if we have the way to work in the context of single interface, or group of interfaces we would have the sort of thin interfaces. What do you think, Nerdfest? I really appreciate your opinion as you mentioned that article.
Yaroslav Yakovlev
A: 

In Eclipse, you have a method called getAdapter() which tries to turn an object into something else. So you can say:

Writer w = text.getAdapter(Writer.class);

Then the text can figure out how to turn itself into a Writer and create one for you. The next step is to have an adapter registry, so you can say:

AdapterRegistry.instance().register(TextDocument.class,
                                    new TextDocumentAdapterFactory ());

In TextDocument, you can then say:

public Object getAdapter(Class c) {
    AdapterRegistry.instance().createAdapter(this, c);
}

This way, you can add adapters for existing objects at a later time.

On the positive side, this makes your code extremely flexible. On the negative side, it makes the code impossible to debug since you can't tell what getAdapter() migth eventually return.

Aaron Digulla
Seems like adapter is a factory. But in your case returning object. So it`s killing strong typing. And the problem is not in make it all flexible and get different instances that implement same interface. To solve this you need to use creational patterns of GoF and you`ll solve it. My problem is getting the right interfaces when working in particular context and hiding other things. How this will help? Note that you may need to have different interfaces in one place if context is so. And implement special class for every interface is at least awkward.
Yaroslav Yakovlev