Juan
Мне нравится думать об интерфейсах как о способе описания класса. Конкретный класс породы собак, например, YorkshireTerrier, может быть потомком родительского класса собак, но он также реализует IFurry, IStubby и IYippieDog. Таким образом, класс определяет, что это за класс, но интерфейс говорит нам об этом.
Преимущество этого в том, что он позволяет мне, например, собрать все IYippieDog и выбросить их в мою коллекцию Ocean. Так что теперь я могу охватить определенный набор объектов и найти те, которые соответствуют критериям, на которые я смотрю, без слишком тщательного изучения класса.
Я считаю, что интерфейсы действительно должны определять подмножество публичного поведения класса. Если он определяет все общедоступное поведение для всех реализуемых классов, то он обычно не должен существовать. Они не говорят мне ничего полезного.
Эта мысль противоречит идее, что у каждого класса должен быть интерфейс, и вы должны написать код для интерфейса. Это нормально, но вы в конечном итоге получаете множество индивидуальных интерфейсов с классами, и это сбивает с толку. Я понимаю, что идея в том, что на самом деле ничего не стоит делать, и теперь вы можете с легкостью менять местами. Однако я нахожу, что я делаю это редко. Большую часть времени я просто изменяю существующий класс на месте, и у меня возникают те же самые проблемы, которые я всегда делал, если нужно изменить публичный интерфейс этого класса, за исключением того, что теперь мне нужно изменить его в двух местах.
Так что, если вы думаете, как я, вы определенно скажете, что Cat и Dog являются IPettable. Это характеристика, которая соответствует им обоим.
Другая часть этого - они должны иметь одинаковый базовый класс? Вопрос в том, должны ли они рассматриваться как одно и то же. Конечно, они оба Животные, но соответствует ли это тому, как мы собираемся использовать их вместе.
Скажем, я хочу собрать все классы животных и положить их в мой контейнер с ковчегом.
Или они должны быть млекопитающими? Может быть, нам нужен какой-нибудь завод по производству животных?
Они вообще должны быть связаны друг с другом? Достаточно ли просто знать, что они оба IPettable?
Я часто испытываю желание вывести целую иерархию классов, когда мне действительно нужен только один класс. Я делаю это в ожидании, когда-нибудь мне это понадобится, и обычно я никогда этого не делаю. Даже когда я это делаю, мне обычно приходится много делать, чтобы это исправить. Это потому, что первый класс, который я создаю, это не Собака, мне не так повезло, это вместо Утконоса. Теперь вся моя иерархия классов основана на странном случае, и у меня много потерянного кода.
В какой-то момент вы также можете обнаружить, что не все кошки являются IPettable (как этот безволосый). Теперь вы можете переместить этот интерфейс ко всем подходящим производным классам. Вы обнаружите, что гораздо менее серьезное изменение, чем внезапно, Кошки больше не являются производными от PettableBase.