Demandez-vous s'il sera courant d'avoir des collections d'objets avec différentes combinaisons de capacités, et si le code peut vouloir exécuter une action sur les éléments, dans une collection, qui le prennent en charge . Si c'est le cas, et s'il y aurait un "comportement par défaut" sensible pour les objets qui n'ont pas de support utile pour une action, il peut être utile d'avoir des interfaces implémentées par un large éventail de classes, pas seulement celles qui peuvent se comporter utilement.
Par exemple, supposons que seuls quelques types de créatures peuvent avoir des Woozles, et on veut que ces créatures aient une NumerOfWoozles
propriété. Si une telle propriété se trouvait dans une interface qui n'était implémentée que par des créatures pouvant avoir des Woozles, alors le code qui voulait trouver le nombre total de Woozles détenus par une collection de créatures de types mixtes devrait dire quelque chose comme:
int total = 0;
foreach (object it in creatures)
{
IWoozleCountable w = trycast(it, IWoozleCountable);
if (w != null) total += w.WoozleCount;
}
Si, cependant, WoozleCount était membre de Creature / ICreature, même si peu de sous-types remplaceraient l'implémentation par défaut de WoozleCount de Creature qui renvoie toujours zéro, le code pourrait être simplifié pour:
int total = 0;
foreach (ICreature it in creatures)
total += it.WoozleCount;
Bien que certaines personnes puissent s'irriter à l'idée que chaque créature implémente une propriété WoozleCount qui n'est vraiment utile que pour quelques sous-types, la propriété aurait un sens pour tous les types, qu'elle soit utile ou non avec des éléments connus pour être de ces types, et je considérerais l'interface "évier de cuisine" comme étant moins une odeur de code que l'opérateur trycast.
IEnumerable
,IEquatable
, etc.