public interface IPlayer {
void Play(IMusic music);
void Play(IMusic music, int volume);
}
This code declares an interface for a player that supports playing music with given volume, or playing music with some default volume level. So, why is that on the interface? Why is the fact that there is such a thing as a "default" value for level something that should pollute an otherwise simple interface for a player?
When overloads are used to hide default values for parameters they have no business being on an interface! Choose the most elaborate way to perform an action and make that the designated method. Only leave that designated method on the interface and take out all others. Implement default values outside of it. Think about this: why would every implementer of that interface have to supply exactly the same default value? And wouldn't it be confusing if they all supplied a different one? And how is that the responsibility of a player to know what the default value for volume is? Doesn't make any sense.
Now, overloads are also used for actually overloading functionality, meaning a method that can be performed on completely different inputs with different logic. Take this for example:
public interface IPlayer {
void Play(IMusic music);
void Play(IVideo video);
}
Make sense? NO! Interface segregation is one of the principles of SOLID design. Split that interface into two, one for each type of input. In fact, better make it a generic one since there's nothing else on it:
public interface IPlayer
void Play(T t);
}
You can still implement IPlayer
Great point about exposing defaulting mechanisms in interfaces. Later in your post, you also make a great point about declaring an interface that serves multiple purposes. I agree with both points. Where I disagree, however is the creation of a generic interface. Interfaces should be specific and not vary, as with the use of type parameters.
ReplyDelete