Подумайте, будет ли обычным иметь коллекции объектов с различными комбинациями способностей, и может ли код захотеть выполнить действие с теми элементами внутри коллекции, которые его поддерживают. . Если это так, и если будет разумное «поведение по умолчанию» для объектов, которые не имеют полезной поддержки для какого-либо действия, может быть полезно иметь интерфейсы, реализованные широким диапазоном классов, а не только теми, которые могут вести себя с пользой.
Например, предположим, что только несколько видов существ могут иметь Woozles, и каждый хочет, чтобы такие существа имели NumerOfWoozles
свойство. Если бы такое свойство было в интерфейсе, который был реализован только существами, которые могут иметь Woozles, то код, который хотел бы найти общее количество Woozles, хранящегося в коллекции существ смешанных типов, должен был бы сказать что-то вроде:
int total = 0;
foreach (object it in creatures)
{
IWoozleCountable w = trycast(it, IWoozleCountable);
if (w != null) total += w.WoozleCount;
}
Однако, если бы WoozleCount был членом Creature / ICreature, хотя несколько подтипов переопределяли бы стандартную реализацию WoozleCount Creature, которая всегда возвращает ноль, код можно упростить до:
int total = 0;
foreach (ICreature it in creatures)
total += it.WoozleCount;
Хотя некоторые люди могут не согласиться с идеей, чтобы каждое Существо реализовало свойство WoozleCount, которое действительно полезно только для нескольких подтипов, свойство будет иметь смысл для всех типов, независимо от того, будет ли оно полезным для элементов, о которых известно, что они принадлежат к этим типам, и я бы расценил интерфейс «кухонной раковины» как нечто меньшее, чем запах кода, чем оператор trycast.
IEnumerable
,IEquatable
и т. Д.