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.

For example:

Say I have classes A, B, C. I have two interfaces, lets call them IAnimal and IDog. IDog inherits from IAnimal. A and B are IDogs, while C is not, but it is an IAnimal.

The important part is that IDog supplies no additional functionality. It is only used to allow A and B, but not C, to be passed as an argument to certain methods.

Is this bad practice?

share|improve this question
6  
IAnimal and IDog are terrible tautology names! –  Jarrod Roberson Jun 13 '12 at 23:41
    
If you need to know at some point later whether X is an IDog or not, then you need to do this. And I agree with Jarrod - please use Animal and Dog for this. –  user1249 Jun 14 '12 at 6:16
4  
@JarrodRoberson while I tend to agree, if you work in the .Net world, you are kind of stuck with it (or will be going against the established convention if you do it differently). –  Daniel B Jun 14 '12 at 6:17
2  
@JarrodRoberson IMHO MyProject.Data.IAnimal and MyProject.Data.Animal are better than MyProject.Data.Interfaces.Animal and MyProject.Data.Implementations.Animal –  Mika Kolari Jun 14 '12 at 7:11
    
The point is there should not be any reason to even care if it is an Interface or Implementation, whether in a repetitive prefix or a namespace either, it is a tautology either way and violates DRY. Dog is all you should care about. PitBull extends Dog doesn't need implementation redundancy either, the word extends tells me all I need to know, read the link I posted in my original comment. –  Jarrod Roberson Jun 14 '12 at 13:08

4 Answers 4

up vote 11 down vote accepted

Interface that has no any member or has exactly same members with another interface that is inherited from same interface called Marker Interface and you are using it as a marker.

It is not bad practice but interface can be replaced by attributes(annotations) if the language that you are using support it.

I can confidently say that it is not bad practice because i have seen heavy usage "Marker Interface" pattern in Orchard Project

Here is sample from Orchard project.

public interface ISingletonDependency : IDependency {}

/// <summary>
/// Base interface for services that may *only* be instantiated in a unit of work.
/// This interface is used to guarantee they are not accidentally referenced by a singleton dependency.
/// </summary>
public interface IUnitOfWorkDependency : IDependency {}

/// <summary>
/// Base interface for services that are instantiated per usage.
/// </summary>
public interface ITransientDependency : IDependency {}

Please refer to Marker Interface.

share|improve this answer
    
Would attributes/annotations support compile-time checking (using C# as a reference language)? I know I could throw an exception if the object doesn't have the attribute, but the interface pattern catches errors at compile time. –  Kendall Frey Jun 13 '12 at 22:58
    
If you are using Marker Interface so you haven't got compile check benefit at all. You are basicaly doing type check by interface. –  Freshblood Jun 13 '12 at 23:03
    
I'm confused. This 'Marker interface' pattern does provide compile-time checks, in that you can't pass a C to a method expecting an IDog. –  Kendall Frey Jun 13 '12 at 23:07
    
If you are using this pattern so you are higly doing reflectional jobs. I mean you are dynamicaly or staticaly doing type checks. I am sure you have something wrong in your use case but i haven't seen how you are using it. –  Freshblood Jun 13 '12 at 23:25
    
Let me describe it as I did in the comment on Telastyn's answer. e.g. I have a Kennel class that stores a list of IDogs. –  Kendall Frey Jun 13 '12 at 23:26

I only know C# well, so I can't say this for OO programming in general, but as a C# example, if you need to categorize classes the obvious options are interfaces, enum property or custom attributes. Usually I would choose the interface no matter what others think.

if(animal is IDog)
{
}
if(animal.Type == AnimalType.Dog)
{
}
if(animal.GetType().GetCustomAttributes(typeof(DogAttribute), false).Any())
{
}


var dogs1 = animals.OfType<IDog>();
var dogs2 = animals.Where(a => a.Type == AnimalType.Dog);
var dogs3 = animals.Where(a => a.GetType().GetCustomAttributes(typeof(DogAttribute), false).Any());


var dogsFromDb1 = session.Query<IDog>();
var dogsFromDb2 = session.Query<Animal>().Where(a => a.Type == AnimalType.Dog);
var dogsFromDb3 = session.Query<Animal>().Where(a => a.GetType().GetCustomAttributes(typeof(DogAttribute),false).Any());


public void DoSomething(IDog dog)
{
}
public void DoSomething(Animal animal)
{
    if(animal.Type != AnimalType.Dog)
    {
        throw new ArgumentException("This method should be used for dogs only.");
    }
}
public void DoSomething(Animal animal)
{
    if(!animal.GetType().GetCustomAttributes(typeof(DogAttribute), false).Any())
    {
        throw new ArgumentException("This method should be used for dogs only.");
    }
}
share|improve this answer
    
The last section of code is mostly what I use this for. I can see that the interface version is obviously shorter, as well as being compile-time checked. –  Kendall Frey Jun 14 '12 at 12:46
    
+1, You know your stuff. –  Emmad Kareem Aug 9 '12 at 9:15

There is nothing wrong with having an interface which inherits another interface without adding new members, if all implementations of the latter interface will be expected to be able to usefully do things which some implementations of the former may not. Indeed, it's a good pattern which IMHO should have been used more in things like the .net Framework, especially since an implementer whose class would naturally satisfy the constraints implied by the more-derived interface can indicate that simply by implementing the more-derived interface, without having to change any of the member-implementation code or declarations.

For example, suppose I have the interfaces:

interface IMaybeMutableFoo {
  Bar Thing {get;set;} // And other properties as well
  bool IsMutable;
  IImmutableFoo AsImmutable();
}
interface IImmutableFoo : IMaybeMutableFoo {};

An implementation of IImmutableFoo.AsImmutable() would be expected to return itself; an mutable class implementing IMaybeMutableFoo.AsImmutable() would be expected to return a new deeply-immutable object containing a snapshot of the data. A routine which wants to store a snapshot of the data held in an IMaybeMutableFoo could offer overloads:

public void StoreData(IImmutableFoo ThingToStore)
{
  // Storing the reference will suffice, since ThingToStore is known to be immutable
}
public void StoreData(IMaybeMutableFoo ThingToStore)
{
  StoreData(ThingToStore.AsImmutable()); // Call the more-specific overload
}

In cases where the compiler doesn't know that the thing to be stored is an IImmutableFoo, it will call AsImmutable(). The function should return quickly if the item is already immutable, but a function call through an interface does still take time. If the compiler knows that the item is already an IImmutableFoo, it can skip the needless function call.

share|improve this answer

Yes, it's a bad practice in almost every language.

Types are not there to encode data; they're an aid to prove that your data goes where it needs to go and behaves like it needs to behave. The only reason to sub-type is if a polymorphic behavior changes (and not always then).

Since there's no typing, what a IDog can do is implied. One programmer thinks one thing, another thinks another and things break down. Or the things it represents increase as you need more fine grained control.

[edit: clarification]

What I mean is that you're doing some logic based on the interface. Why can some methods only work with dogs and others any animal? That difference is an implied contract since there is no actual member that provides the difference; no actual data in the system. The only difference is the interface (hence the 'no typing' comment), and what that means will differ between programmers. [/edit]

Certain languages provide trait mechanisms where this isn't too bad but those tend to focus on capabilities, not refinement. I've little experience with them so can't speak to the best practices there. In C++/Java/C# though... not good.

share|improve this answer
    
I'm confused by your middle two paragraphs. What do you mean by 'sub-type'? I'm using interfaces, which are contracts, not implementations, and I'm not sure how your comments apply. What do you mean by 'no typing'? What do you mean by 'implied'? An IDog can do everything that an IAnimal can, but isn't guaranteed to be able to do more. –  Kendall Frey Jun 13 '12 at 23:05
    
Thanks for the clarification. In my specific case, I'm not exactly using the interfaces differently. It can probably be best described by saying I have a Kennel class that stores a list of IDogs. –  Kendall Frey Jun 13 '12 at 23:23
    
@KendallFrey: Either you're casting out of the interface (bad), or you're creating an artificial distinction that smells of an incorrect abstraction. –  Telastyn Jun 13 '12 at 23:29
2  
@Telastyn - Purpose of such as interface is that providing a metadata –  Freshblood Jun 13 '12 at 23:36
1  
@Telastyn: So how do attributes apply to compile-time checking? AFAIK, in C#, attributes can only be used at runtime. –  Kendall Frey Jun 13 '12 at 23:46

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.