Take the 2-minute tour ×
Programmers Stack Exchange is a question and answer site for professional programmers interested in conceptual questions about software development. It's 100% free, no registration required.

When should or shouldn't a variable be declared as a custom Interface type?

When walking through some code, I required to know what was happening here:

Public Class MyMainProject
    ....
    Public Sub DoMyWork()
        Dim objIMyInterface As IMyInterface
        ....
        objIMyInterface = GetReturnObject()
    End Sub
    ....
End Class

According to what I saw, objIMyInterface is only being used for one thing. I didn't know how many classes implement it, but there's no casting of similar types in this code. objIMyInterface is used just like a regular type, not anonymous in the least. Second of all, my research helped a little...

GetReturnObject happens to return an instance of IMyInterface. The return object of GetReturnObject, of course, has a call to another method.

Public Function GetReturnObject() As IMyInterface
    Dim retObject As IMyInterface
    ...
            retObject = AnotherMethod()
    ...
    Return retObject
End Function

So I try to step into AnotherMethod, but it's in a project with no symbols. So after some research, I find the source and go through it. After repeating this process a few times, I eventually get to something like this:

Public Function FinalMethod() As IMyInterface
    Dim FinalObject As MyClassType
    ...
            FinalObject = GetMyClassType()
    ...
    Return FinalObject 
End Function

Yay! GetMyClassType returns MyClassType! I go to that Class and of course:

Public Class MyClassType
    Implements IMyInterface
    ...
End Class

What I end up finding out is that IMyInterface is used by nothing else but this class. No biggie, it's all good code by the looks of it. But then I go back to my original project I notice this:

Public Class MyMainProject
    ....
    Public Sub DoMyWork()
        Dim objIMyInterface As IMyInterface
        ....
        objIMyInterface = GetReturnObject()
    End Sub
    ....
    Public Sub OtherWork()
        Dim objMyType As MyClassType
        ....
    End Sub
    ....
End Class

The guy who created this is long gone, but I'd like to know what your thoughts are on which method should be used. Should I declare both as IMyInterface? Or both as MyClassType? The code works fine either way.

share|improve this question
1  
How bad you want to prevent the next programmer from having to go through this whole process? It could be you in 6 months. –  JeffO Jun 14 '13 at 12:12
    
You and Rich obviously agree with me. I was hoping for some discussion of why I should KEEP the interface declaration in this example. That way, I'm prepared to argue my case if I know some possibly opposing views. y'know? –  Suamere Jun 14 '13 at 13:19
add comment

3 Answers

up vote 2 down vote accepted

For an interface with a single implementing class, using both the interface and the concrete class in a consuming class is wrong UNLESS the interface does not include all of the properties/methods of the concrete class.

Choose one or the other, and unless it's needed/helpful for testing or only exposes a subset of the functionality of the class, drop the interface.

And not just in this class, everywhere. An interface is used to abstract properties/methods from a concrete class, allowing several classes to be used interchangeably. If there are no other classes, and there is no likely hood of other classes, then an interface is an unnecessary abstraction. Unnecessary abstractions should be avoided.

share|improve this answer
    
That's the same call I made, J. Unnecessary abstraction is unnecessary, lol. I agree with Joppe too where he feels it is best to wait for reuse then refactor for abstractions, rather than doing it up-front on a hunch. –  Suamere Jun 24 '13 at 19:20
add comment

Normally, you'd only declare a return type of an interface if you weren't absolutely certain what type you were going to get, but you did know that whatever type came back, it would definitely certainly implement that interface.

For example...

public Interface IMammal()
{
    public void Breastfeed();
}

public class Cat : IMammal()
{
    public void Breastfeed()
    {
        // stuff happens here
    }

    public bool Killsmice()
    {
        return true;
    }
}

public class Elephant : IMammal
{
    public void Breastfeed()
    {
        // stuff
    }

    public bool HasTrunk()
    {
        return true;
    }
}

Now, let's look at when this might be useful.

public class Zoo
{
    public void AnimalType(IMammal mammal)
    {
        // here, the Breastfeed method could safely be called, but the HasTrunk or
        // KillsMice methods (they're methods because they are neither get nor set)
        // cannot safely be called. All this method knows is that it's getting a
        // class which implements IMammal
    }
}

In your case, you've got an interface which only applies to one single class. Provided you're certain you'll never create another class which implements the interface, you're better off instantiating the actual class - your code will be more readable.

share|improve this answer
add comment

Perhaps the programmer creating the interface thought it would be an abstraction that would get some reuse (multiple implementations) somewhere in the future (YAGNI though, it's better to wait for reuse and then refactor to abstractions).

He might have created the interface so he could create mock objects around it to use in unit tests. Creating interfaces purely for testing purposes is controversial to some (it initially was for me).

Interfaces are sometimes useful to formulate calls and requests from caller's perspective. Even if there is only one implementation that can respond it may still be useful semantically or conceptually. It may also shield the implementing class' public interface, perhaps used from other perspectives.

share|improve this answer
add comment

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.