Java 8 методы по умолчанию как черты: безопасный?



- это безопасная практика, чтобы использовать методы по умолчанию, как бедный человек, черт в Java 8?



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



I есть следующий практический случай использования внимание:



public interface Loggable {
default Logger logger() {
return LoggerFactory.getLogger(this.getClass());
}
}


или, возможно, определить PeriodTrait:



public interface PeriodeTrait {
Date getStartDate();
Date getEndDate();
default isValid(Date atDate) {
...
}
}


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



и это нормально / безопасно использовать методы по умолчанию в качестве основных черт, или я должен беспокоиться о непредвиденных побочных эффектов?



несколько вопросов на SO связаны с Java vs Scala черты; это не имеет значения здесь. Я тоже не просто спрашиваю мнения. Вместо этого я ищу авторитетный ответ или, по крайней мере, понимание поля: если вы использовали методы по умолчанию в качестве черт в своем корпоративном проекте, оказалось ли это бомбой замедленного действия?

692   1  

1 ответ:

короткий ответ: это безопасно, если вы используете их спокойно :)

язвительный ответ: скажи мне, что вы имею в виду черты, и, возможно, я дам вам лучший ответ:)

на полном серьезе, термин "черта" не определяются. Многие разработчики Java наиболее знакомы с чертами, как они выражены в Scala, но Scala далеко не первый язык, чтобы иметь черты, либо по имени, либо по сути.

например, в Scala, черты являются статусными (может иметь var переменные); в крепости они являются чистым поведением. Интерфейсы Java с методами по умолчанию не имеют состояния; означает ли это, что они не являются чертами? (Подсказка: это был вопрос с подвохом.)

опять же, в Scala черты составляются путем линеаризации; если класс A расширяет черты X и Y, то порядок, в котором X и Y смешиваются в определяет, как конфликты между X и Y решаются. В Java, это механизм линеаризации отсутствует (он был отклонен, отчасти, потому что он был слишком "не похож на Java".)

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

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

вот некоторые использовать случаи, которые хорошо вписываются в цели дизайна:

  • эволюция интерфейса. Здесь мы добавляем новый метод к существующему интерфейсу, который имеет разумную реализацию по умолчанию с точки зрения существующих методов на этом интерфейсе. Примером может быть добавление forEach метод Collection, где реализация по умолчанию записывается в терминах iterator() метод.

  • "дополнительно" методами. Здесь, дизайнер интерфейса говорит "Разработчики не должны реализовывать этот метод, если они готовы жить с ограничениями в функциональности, что влечет за собой". Например, Iterator.remove был задан по умолчанию, который бросает UnsupportedOperationException; так как подавляющее большинство реализаций Iterator в любом случае это поведение по умолчанию делает этот метод, по сути, необязательно. (Если поведение от AbstractCollection были выражены как значения по умолчанию на Collection, мы могли бы сделать то же самое для методов мутационной.)

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

  • комбинаторы. Это композиционные методы, которые создают новые экземпляры интерфейса на основе текущего экземпляра. Например, методы Predicate.and() или Comparator.thenComparing() примеры комбинаторы.

если вы предоставляете реализацию по умолчанию, вы также должны предоставить некоторую спецификацию для значения по умолчанию (в JDK мы используем @implSpec тег javadoc для этого), чтобы помочь разработчикам понять, хотят ли они, чтобы переопределить метод или нет. Некоторые значения по умолчанию, такие как методы удобства и комбинаторы, почти никогда не переопределяются; другие, такие как дополнительные методы, часто переопределяются. Вам нужно предоставить достаточную спецификацию (не только документация) о том, что обещает сделать по умолчанию, поэтому разработчик может принять разумное решение о том, нужно ли его переопределять.

Comments

    Ничего не найдено.