Suppose I have a various entities in my model (using EF), say User, Product, Invoice and Order.
I am writing a user control that can can print the summaries of entity objects in my application where the entities belong to pre-decided set, in this case I say that summaries of User and Product can be summarized.
The summaries will all only have a ID and a description, so I create a simple interface for this:
public interface ISummarizableEntity {
public string ID { get; }
public string Description { get; }
}
Then for the entities in question, I create a partial class that implements this interface:
public partial class User : ISummarizableEntity
{
public string ID
{
get{ return UserID.ToString(); }
}
public string Description
{
get{ return String.Format("{0} {1} is from {2} and is {3} years old", FirstName, LastName, Country, Age); }
}
}
public partial class Product: ISummarizableEntity
{
public string ID
{
get{ return ProductID.ToString(); }
}
public string Description
{
get{ return String.Format("{0} weighs {1}{2} and belongs in the {3} department", ProductName, WeightValue, WeightUnit, Department); }
}
}
This way my user control / partial view can just bind to any collection of ISummarizableEntity and doesn't need to be interested in the source at all. I have been told that interfaces shouldn't be used as datatypes but I didn't get more information than that. As far as I can see, although interfaces normally describe behavior, just using properties isn't an anti-pattern in itself as properties are just syntactic sugar for getters/setters anyway.
I could create a concrete datatype and map from the entities to that but I can't see the benefit. I could make the entity objects inherit from an abstract class and then define the properties but then I am locking the entities to no further use as we can't have multiple inheritance. I am also open to having any object being ISummarizableEntity if I wanted (obviously I would rename the interface)
The solution I am using in my mind is maintainable, extensible, testable and fairly robust. Can you see the anti-pattern here?
Best Answer
Interfaces don't describe behaviour. Quite the opposite, sometimes.
Interfaces describe contracts, such as "if I am to offer this object to any method that accepts an ISummarizableEntity, this object must be an entity that is able to summarize itself" -- in your case, that is defined as being able to return a string ID and a string Description.
That's a perfect use of interfaces. No anti-pattern here.