Можно ли добавлять стандартные реализации к методам интерфейса, который представляет собой прослушиватель?
В моем проекте используется определенная библиотека. Эта библиотека имеет интерфейс, который имеет около 15 методов.
Цель этого интерфейса - дать возможность подписаться на некоторые события, которые генерируются в библиотеке. Класс слушателя в приложении может реализовать этот интерфейс и зарегистрировать себя в качестве слушателя в библиотеке для получения событий.
Все методы в этом интерфейсе - это фактически события. Могут быть слушатели, которым требуется только одно или два события из многих событий в интерфейсе. Несмотря на то, что слушатель интересуется только несколькими событиями, слушатель должен реализовать все методы при расширении интерфейса.
Поэтому я попросил разработчика этой библиотеки добавить пустые реализации по умолчанию в методы в интерфейсе.
Но разработчик библиотеки отказывается добавлять стандартные реализации, заявляя, что он нарушит лучшие практики Java и использование реализаций по умолчанию в интерфейсных методах идет вразрез с целями интерфейсов.
Но, как я понимаю, метод в этом интерфейсе не указывает какое-то действие, на которое должен быть способен реализатор этого интерфейса. Метод в этом интерфейсе скорее определяет событие, которое может заинтересовать разработчик. Поэтому я не вижу ясной причины не добавлять стандартные реализации.
Итак, добавляет ли реализация по умолчанию к этому интерфейсу нарушить лучшие практики java?
Ответы
Ответ 1
Но разработчик библиотеки отказывается добавлять стандартные реализации, заявив, что он нарушит лучшие практики Java и использует реализации в интерфейсных методах идут вразрез с целью интерфейсы.
Этот аргумент был действителен до тех пор, пока не будут введены методы интерфейса по умолчанию.
Теперь вашему коллеге пришлось бы утверждать, что JLS Java 8 извращенных интерфейсов и JDK теперь содержат классы, которые противоречат назначению интерфейсов. Тем не менее это жизнеспособная крайняя точка зрения, но бесплодная.
Вы просто можете избежать обсуждения, выведя собственный интерфейс из интерфейса библиотеки и предоставляя стандартные пустые реализации для всех унаследованных методов.
public interface MyInterface extends LibraryInterface {
@Override default public void event1() {
}
...
}
Или вы оба можете просмотреть следующий дизайн, который мне кажется сомнительным, и который привел к обсуждению метода по умолчанию в интерфейсах:
Несмотря на то, что слушателя интересует только несколько событий, слушатель должен реализовать все методы при расширении интерфейса.
Решением может быть просто разделить большой интерфейс на многие более мелкие.
Ответ 2
Разработчик библиотеки ошибается в этом (я даже осмеливаюсь пропустить IMHO).
Одна из причин того, что многие вспомогательные (как абстрактные, так и конкретные) классы в Java были введены в прошлом, - это в точности отсутствие таких функций, как методы интерфейса по умолчанию (например, классы адаптеров в Swing, которые очень напоминают проблемы, которые вы испытываете спрашивают).
Если не использовать неправильно, в некоторых ситуациях желательно многократное наследование, и, как мы все знаем, расширяя класс "помощник" в Java, мы теряем способность наследовать что-либо еще.
Собственно, это упоминается в официальном учебнике Java, раздел "Абстрактные классы по сравнению с интерфейсами":
Рассмотрите возможность использования интерфейсов, если какое-либо из этих утверждений относится к вашему ситуация:
- Вы ожидаете, что не связанные классы будут реализовывать ваш интерфейс. Например, реализованы интерфейсы Comparable и Cloneable многими несвязанными классами.
- Вы хотите указать поведение конкретного типа данных, но не обеспокоены тем, кто реализует его поведение.
- Вы хотите использовать множественное наследование типа.
Вторая и третья точки - идеальное совпадение для вашего случая использования, я думаю.
Ответ 3
Поскольку методы по умолчанию позволяют нам добавлять новые функциональные возможности в интерфейсы, не нарушая классы, реализующие этот интерфейс, поэтому он определенно не является хорошей практикой, потому что он сочетает в себе достоинства интерфейсов и абстрактных классов, но поскольку это не вариант, я бы настоятельно рекомендуем, чтобы вы предоставили свой собственный класс реализации скелета, поскольку эта "методология" используется во всей структуре коллекций в java, и это просто мое скромное мнение.