Объединены общие границы антипаттерна?

как продолжение моего предыдущий вопрос Наличие функции с комбинированными общими границами, такими как:

<T extends Foo & Bar> void doStuff(T argument) {
  //do stuff wich should only be done if arguments is both foo and bar
}

Поскольку это не может быть приведено из неопределенного объекта, вам необходимо знать какой-то объект, который фактически реализует эти интерфейсы. Мне кажется, что необходимость знать конкретный тип аргумента объекта для передачи в doStuff(T a) является нарушением закона Деметры.

Функция не указывает, что необходимо знать фактический класс (может быть много разных), и я действительно не хочу знать об этом, поскольку знание этого класса увеличивает зависимость в моей базе кода.

использует эти границы как антипаттерн? и если да, то как лучше всего этого избежать?

сценарий случая включал один интерфейс, определяющий, что объект является постоянным, а другой указанный объект имел связанную сущность. функция doStuff(T a) в этом случае сохранила связанный объект, когда он был сохранен. однако непостоянные объекты также могут иметь связанные объекты, но не должны обрабатываться функцией doStuff(T a).

Этот вопрос кажется связанным с вопросом преобразовать в комбинированный универсальный (того же автора).

Henrik Gustafsson 26.11.2008 14:26

это так, но я подумал, что для ясности было бы лучше сделать это другим вопросом

pvgoddijn 26.11.2008 16:09

Ну, вы, очевидно, все об этом знали, я просто думал обо всех, кому может понадобиться больше контекста :)

Henrik Gustafsson 26.11.2008 16:13
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
Как вычислять биты и понимать побитовые операторы в Java - объяснение с примерами
Как вычислять биты и понимать побитовые операторы в Java - объяснение с примерами
В компьютерном программировании биты играют важнейшую роль в представлении и манипулировании данными на двоичном уровне. Побитовые операции...
Поднятие тревоги для долго выполняющихся методов в Spring Boot
Поднятие тревоги для долго выполняющихся методов в Spring Boot
Приходилось ли вам сталкиваться с требованиями, в которых вас могли попросить поднять тревогу или выдать ошибку, когда метод Java занимает больше...
Полный курс Java для разработчиков веб-сайтов и приложений
Полный курс Java для разработчиков веб-сайтов и приложений
Получите сертификат Java Web и Application Developer, используя наш курс.
2
3
766
3

Ответы 3

Я бы не стал рассматривать комбинированные общие границы как антипаттерн. По крайней мере, у меня есть несколько вариантов их использования в моем коде. Например, следующий пример кода находит самый большой экземпляр Number в коллекции с помощью compareTo из интерфейса Comparable:

<T extends Number & Comparable<T>> T max(Collection<T> numbers)

Зачем T нужно продлевать номер? Не работает ли он на полностью заказанном типе?

Miserable Variable 26.11.2008 14:02

Number на самом деле имеет значение для стертой подписи метода (он вернет Number вместо Comparable). В более общих Collections.max он возвращает T extends Object & Comparable <? super T>, это потому, что метод до версии 1.5 возвращал Object вместо Comparable.

Tom Hawtin - tackline 26.11.2008 14:23

it seems to me that needing to know the specific type of the object argument to pass to doStuff(T a) is a violation of Demeter's law

Я не согласен. Я не понимаю как

T<? extends Foo & Bar> void doStuff(T argument) 

требует дополнительных знаний аргумента для передачи, затем

T<? extends Foo> void doStuff(T argument) 

Или даже больше, чем просто

void doStuff(T argument) 

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

потому что в первом примере нам нужно явно передать некоторый класс A, реализующий Foo, bar, что означает, что нам нужно знать класс A, а во втором примере нам нужно знать только ИНТЕРФЕЙС Foo (не класс B реализует Foo)

pvgoddijn 26.11.2008 14:12

Антипаттерн - это литье.

Тем не менее, причудливая работа с дженериками может сбивать с толку неопытных программистов. Использование таких типов и методов должно быть намного проще, чем их реализация.

Другие вопросы по теме