Reputation: 2983
I have 2 objects that inherit from an interface i created which worked nicely. The Objects are injected into another object calls the methods of both the object. The methods of the objects perform some simple XML manipulation which is then returned to the worker object.
I now have a change request which affects one object that inherits from the interface but not the other and I'm at a loss as to how I should handle this. I've created a couple of new methods and I simply throw a not implemented exception if its not used. This doesn't seem "Best Practice" to me. What is the best way to handle this scenario?
Upvotes: 0
Views: 65
Reputation: 50313
I think that this is a situation where the Interface Segregation Principle comes in place.
If you find yourself having two objects for which it does not make sense to expose the same set of public members, then probably they should not implement the same interface. Or at least not only the same interface. You have two options here, depending on your application's logic:
Leave the original interface as is, and the first class (the one not needing extra methods) unmodified. Define a new interface only for the new methods, and make the second class implement both interfaces.
Define a new interface that inherits from the old one and contains the new methods. Leave your first class unmodified, and have your second class implement the new interface.
Implementing an interface and doing nothing more than throwing an exception in some methods is indeed a bad practice, as it breaks the Liskov substitution principle.
Upvotes: 4
Reputation: 27605
You could extend the interface like this:
public interface SimpleInterface
{
void SimpleMethod();
void OtherMethod();
}
public interface ExpandedInterface : SimpleInterface
{
void ExpandedMethod();
void OtherExpandedMethod();
}
That way you could declare, on your client code, if you really need an expanded interface implementer (in which case you should pass only an instance of the subset of concrete classes that implement ExpandedInterface
) or it is enough to use a SimpleInterface
implementer (in which case you can pass either).
The situation you presented (needing to add funcion to one object, but not other) has more to do with the client code than the interface implementers themselves. You have to think: "in this client class, what do I really need: an instance of SimpleInterface
, or an instance of ExtendedInterface
?"
Upvotes: 0
Reputation: 111920
An interface doesn't "need" to be fully implemented... Even in .NET there are classes that implement partially an interface (and that throw NotSupportedException()
when used in an "illegal" way)... For example arrays are IList<>
that don't support Add()
or Remove()
...
Or the Stream
abstract class, that has an additional "pattern": CanRead
, CanWrite
, CanSeek
, ..., so there are methods, and properties that tell if it is legal to use those methods.
Another way is to use an additional interface, and try casting it with as
operator. The Entity Framework for example "returns" IQueryable<T>
, that "are" IEnumerable<T>
... But those objects even support the IDbAsyncEnumerable<T>
interface... but not all the IQueryable<T>
are IDbAsyncEnumerable<T>
. You have to do a cast and see if the interface is present or not.
Upvotes: 0