Эффективный обзор Java (Серия из 78 частей)
Сегодня мы снова сосредоточимся на интерфейсах. Основное внимание в сегодняшней главе было в основном уделено функции, которая была добавлена в Java 8, методам по умолчанию . Проблема, которую пытаются решить методы default , заключается в том, что до Java 8, как только интерфейс был выпущен в дикую природу, вы никогда не могли безопасно его изменить. Если бы вы это сделали, классы, которые его реализовали, столкнулись бы с ошибкой, поскольку они больше не будут реализовывать полный интерфейс. Итак, как методы по умолчанию пытаются решить эту проблему? То, что они позволяют нам делать, – это предоставлять реализацию по умолчанию для определенного метода, чтобы мы могли разрабатывать интерфейс, не требуя от потребителя услуги немедленной реализации этого метода.
Это звучит как отличная идея, и это может быть отличным инструментом, но о чем мы должны знать при использовании метода по умолчанию ? Основная проблема заключается в том, что у нас нет гарантии, что наша реализация по умолчанию будет работать со всеми реализациями интерфейса. Примером того, как это может нас укусить, является удалить, если
по умолчанию метод добавлен в интерфейс коллекции
в Java 8. Этот метод использует Предикат
и он выполняет итерацию по коллекции и вызывает remove для всех записей, соответствующих предикату. Это кажется простой, логичной реализацией, и она действительно работает большую часть времени. Однако, например, в библиотеке Apache Commons есть SynchronizedCollection
, которая реализует интерфейс Collection
и в основном перенаправляет все запросы в резервную коллекцию после блокировки объекта. Этот метод не переопределяет функцию удалить, если
и, таким образом, наследует реализацию по умолчанию. Однако эта реализация по умолчанию удалить, если
нарушает инварианты класса, поскольку она не блокирует объект.
Эта глава заканчивается довольно короткой и простой, итог главы таков: несмотря на то, что у нас есть методы по умолчанию в качестве инструмента в нашем наборе инструментов, мы не должны рассчитывать на использование этой способности. Точно так же, как когда мы реализуем классы для наследования, мы должны попробовать реализовать несколько классов в новом интерфейсе, а также рассмотреть возможность того, чтобы другой человек реализовал класс в вашем интерфейсе. Это позволяет нам получить опыт использования интерфейса, и мы можем увидеть, не хватает ли чего-то или в нашем интерфейсе есть ненужные элементы. Таким образом, хотя мы, возможно, сможем исправить некоторые ошибки постфактум с помощью методов по умолчанию, мы не должны рассчитывать на это и прилагать усилия, чтобы создать все правильно с первого раза.
Эффективный обзор Java (Серия из 78 частей)
Оригинал: “https://dev.to/kylec32/effective-java-design-interfaces-for-posterity-1dgj”