Пожалуйста, объясните использование поставщика интерфейса (в Гуаве) с подходящим примером.
Пример поставщика Google Guava
Ответ 1
Интерфейс Supplier
представляет собой просто абстракцию функции no-arg, которая возвращает значение... это средство получения какого-либо экземпляра или экземпляра объекта. Поскольку он настолько общий, его можно использовать как можно больше. Джаред объяснил, как фабрики Multimaps
используют его как factory для создания нового экземпляра Collection
некоторого типа для значений.
Учитывая простоту интерфейса, он также допускает очень сильное украшение поведения Supplier
, обертывая его в другой Supplier
, который каким-то образом изменяет его поведение. Одним из примеров этого является воспоминание. Я сам использовал метод Suppliers.memoizeWithExpiration
как простой способ сделать это, поэтому некоторые данные будут считываться с сервера не чаще одного раза за определенный период времени.
Я также рекомендую взглянуть на Guice и как в нем используется интерфейс Provider
. Provider
в точности эквивалентен Supplier
и имеет решающее значение для того, как работает Guice.
-
Provider
позволяет пользователям определять собственный способ создания новых объектов данного класса. Пользователи могут написать методget()
, который может выполнять любой код, необходимый для создания нового объекта, поэтому они не ограничиваются тем, что для создания объектов используют только конструкторы Guice. Здесь они используют его для определения пользовательского factory для нового экземпляра объекта. - Guice позволяет вводить
Provider
любой зависимости. Это может возвращать новый экземпляр каждый раз, когда вызываетсяget()
, или он всегда может возвращать один экземпляр или что-то среднее между ними, в зависимости от того, как привязывается привязкаProvider
. Это также позволяет "ленивую инстанцировку" зависимостей...Provider
дает классу средство создания объекта без необходимости фактически создавать объект раньше времени. Экземпляр объекта не нужно создавать до тех пор, пока не будет выдан вызовget()
. - Как указано выше,
Provider
составляют основу области определения в Guice. Если вы посмотрите на интерфейс Scope, вы заметите, что его единственный методProvider<T> scope(Key<T> key, Provider<T> unscoped)
определяется в терминахProvider
s, Этот метод принимает что-то, что создает новый экземпляр объекта (Provider<T> unscoped
) и возвращаетProvider<T>
на основе того, что применяет любую политику, определяемую областью, потенциально возвращающую некоторый кешированный экземпляр объекта, а не создавая новый. Область по умолчаниюNO_SCOPE
просто проходит через поставщикаunscoped
, то есть каждый раз создается новый экземпляр. ОбластьSINGLETON
кэширует результат первого вызоваunscoped.get()
и после этого возвращает этот единственный экземпляр, гарантируя, что все, что зависит от объекта с одноэлементной областью, получает ссылку на этот единственный объект. Обратите внимание, чтоProvider
, возвращаемый методомSINGLETON
scopescope
, делает то же самое, что иSupplier
, возвращаемоеSuppliers.memoize
(хотя это немного сложнее).
Ответ 2
Основная причина, по которой мы включили Поставщика в Гуаву, заключалась в поддержке методов Multimaps, которые генерируют произвольные Multimaps, такие как
public static <K,V> Multimap<K,V> newMultimap(Map<K,Collection<V>> map,
Supplier<? extends Collection<V>> factory)
Поставщик создает коллекцию, которая содержит все значения для данного ключа. Multimap использует Поставщика всякий раз, когда вы храните пару ключ-значение с ключом, который еще не включен в Multimap.
Ответ 3
Это способ обеспечения косвенного объекта. Вы можете каждый раз указывать другой объект Supplier.get() is
.
Например, у меня есть одноэлементный класс с именем SmtpMailSender
, который принимает имя хоста для SMTP-сервера. Однако имя хоста может меняться во время выполнения, поэтому вместо принятия String hostname
требуется Supplier<String> hostname
.
Ответ 4
Другой пример использования Поставщика:
http://javawayoflife.blogspot.com/2010/06/unit-test-and-new-date.html
Ответ 5
Пример использования Поставщика:
Ответ 6
Еще одно отличное использование класса - развязка - если компонент использует только другой для получения значения, не зависит от конкретной реализации, а от этого интерфейса.
Во всяком случае, здесь есть пример кода: http://www.slideshare.net/tfnico/google-guava
Ответ 7
Смотрите класс Suppliers, и я думаю, что методы там каким-то образом ответят на ваш вопрос.