Добавить в корзинуПозвонить
Найти в Дзене
Геннадий Шушпанов

Феномен интерфейса

Интерфейсы. Изначально ООП обходилось без них. Позже в C++ была неудачная попытка использовать вместо них классы, которая, однако, привела к пониманию проблемы и открыла путь к её решению. Нужна была абстракция поведения вне классификации и интерфейсы воплотили её. Окружающие нас объекты дружно игнорируют SRP -- гвоздь, ведро, автомобиль помимо своего индивидуального поведения имеют и общее: их можно купить, у них есть положение и габариты и они ржавеют со временем. Для отражения общих черт не хватает иерархической классификации, при которой наследование поведения возможно лишь по одной линии. Можно добавить в иерархию промежуточные классы, поскольку общее поведение есть у каждого из приведенных объектов, но добавление в список стеклянного стакана нарушит идиллию, поскольку он не ржавеет. Интерфейсы товара, тела и взаимодействия с атмосферой, обеспечат полиморфизм в работе с объектами без необходимости сводить всё в одну иерархию. Классы имеют реализацию, которая всегда тянет за собой
Оглавление

Интерфейсы. Изначально ООП обходилось без них. Позже в C++ была неудачная попытка использовать вместо них классы, которая, однако, привела к пониманию проблемы и открыла путь к её решению. Нужна была абстракция поведения вне классификации и интерфейсы воплотили её.

Множественное наследование

Окружающие нас объекты дружно игнорируют SRP -- гвоздь, ведро, автомобиль помимо своего индивидуального поведения имеют и общее: их можно купить, у них есть положение и габариты и они ржавеют со временем. Для отражения общих черт не хватает иерархической классификации, при которой наследование поведения возможно лишь по одной линии. Можно добавить в иерархию промежуточные классы, поскольку общее поведение есть у каждого из приведенных объектов, но добавление в список стеклянного стакана нарушит идиллию, поскольку он не ржавеет. Интерфейсы товара, тела и взаимодействия с атмосферой, обеспечат полиморфизм в работе с объектами без необходимости сводить всё в одну иерархию.

Сокрытие реализации

Классы имеют реализацию, которая всегда тянет за собой зависимости. Допустим у нас есть набор классов для управлением потоком автомобилей. Но в новом проекте нам не нужна настолько подробная модель автомобиля. Мы можем конечно, добавить новую реализацию и понатыкать операторов условной компиляции, но проще использовать интерфейсы. Они обеспечат независимость от реализации и полиморфизм, а IoC-контенер сборку с нужными классами.

Разделение реализаций

Случай сходный с предыдущим, но в данном случае проект один, но разные его части требуют разной реализации. Например, у нас есть внешний сервис, откуда мы получаем информацию о заказах, обрабатываем её, и записываем в нашу базу данных. Модели заказов у нас и поставщика схожие, но разные. В данном случае интерфейсы помогут инкапсулировать реализации для поставщика и базы данных и обеспечить полиморфную обработку.

Инверсия зависимости

А вот инвертировать зависимости интерфейсы не могут. Зависимости между классами определяются их поведением, а интерфейсы поведение классов не меняют. Они скрывают реализацию, но не могут скрыть поведение. Поэтому, если у вас класс А зависит от класса Б, то и с интерфейсом А будет зависеть от Б, но уже через интерфейс, поскольку интерфейс определяется поведением Б, которое использует А.

ISP XOR LSP

Нужно ли делить интерфейсы? Можно, но без фанатизма. Границы разделения определяются с одной стороны классом А, который использует интерфейс и требует, чтобы в нем был представлен полный набор методов нужного поведения, а с другой возможностями классов Б, В, ..., для их реализации. Проблема возникает если эти множества не равны. В этом случае ищите компромисс между заглушками в Б, В, ..., и проверками на применимость методов в А. Одним из принципов придется пожертвовать.