Подтвердить что ты не робот

Должен ли я определять интерфейсы на языках с утиным типом?

Я собираюсь написать свое первое приложение на утином языке (Groovy).

Если бы я должен был написать одно и то же приложение на статическом типизированном языке, тогда мне нужно было бы определить некоторые интерфейсы. Очевидно, из-за того, что утка печатается в Groovy, они на самом деле не требуются. В настоящий момент я думаю, что имеет смысл определять их в любом случае как документацию о методах, которые необходимо реализовать в разных объектах. Я пропустил точку?

4b9b3361

Ответ 1

Я читал об этом недавно здесь на SO (и я не могу найти ссылку прямо сейчас, но это одна из тех, "почему являются динамичными языками хорошими?", и большой ответ С. Лотта с много комментариев), и ответ:

Вы могли бы. В Groovy особенно вы можете определить интерфейсы в Java или Groovy и реализовать их. Тем не менее, с утиным типом (который Groovy разрешает, но также допускает явные типы), многие люди скажут "зачем беспокоиться"? Источником является его собственная документация, интерфейс находится в источнике, "используйте источник" и т.д.

Лично это меня раздражает - мне нравится время компиляции (или действительно, dev-time), которое дает мне Java, но это еще одна дискуссия. Если вы используете Groovy, это потому, что вы хотите написать этот блестяще сжатый и понятный код, который исходит из утиного ввода. В этом случае следует избегать интерфейсов, кроме случаев, когда это необходимо.

Где они нужны? Между частями программы и в Public API для программы (хотя они также могут быть абстрактными классами). В противном случае, я бы сказал, что вы должны стараться избегать их в языках с утиным языком. Это заставляет вас писать документы в классах или писать код, который настолько ясен, что это одно и то же.

Я думаю, что это ужасная практика, ОДНАКО, это часть перехода парадигмы к динамичным языкам. И я думаю, что если вы избегаете достаточно отделять интерфейс от реализации, вы поймете "почему" за ним. Я все еще этого не делаю, хотя он имеет много общего с не повторяющимся кодом (сохраняя DRY).

Изменить: Получил определенную ясность от компьютера:) Одна из основных причин, по которым НЕ отделять интерфейс от реализации, заключается в том, чтобы вы отошли от зависимости от типов, В утином, как вы знаете, меня не волнует, является ли он исполнителем интерфейса Vehicle (например). Мне все равно, если он имеет метод go с двумя параметрами. Итак, чем больше вы работаете с интерфейсами, тем больше вы пишете Java в Groovy ( "вы можете писать Fortran на любом языке" ). Этого следует избегать, так как новые языки открывают вам новые вещи.

Ответ 2

Я не знаком с groovy, но, вообще говоря, нет, вам не нужно определять интерфейсы на свободно типизированных языках.

  • Вы бы повторялись, если вам нужно изменить подписи методов, тогда вам нужно сделать это в двух местах, а не в одном.

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

  • Большинство динамических языков имеют для них хорошую IDE, с завершением метода, что еще больше уменьшает необходимость в отдельном интерфейсе.

  • Методы могут быть связаны и несвязаны в динамических языках. Таким образом, вы можете и, вероятно, будете в конечном итоге создавать объекты, которые не соответствуют интерфейсу. Наличие отдельного интерфейса может привести к запутыванию людей, читающих ваш код.

Ответ 3

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

PS: groovy не мой язык, поэтому я действительно не знаю, можно ли вообще там определять интерфейсы.

Ответ 4

В некоторых случаях да. У меня есть пример, когда я создаю класс Groovy, который вводится в класс Java с помощью Spring. Я создал интерфейс с использованием таких дженериков, как это:

//interface injected to a java class
public interface SomeInterface {
    <T> T getSomething(int version, Long id);
}

Затем реализация Groovy выглядит следующим образом:

//Groovy impelentation
class SomeInterfaceImpl implements SomeInterface {
    def getSomething(int version, Long id) {
        //use duck typing to create similar objects based on version
    }
}

Моим примером является то, что я использую JAXB и XJC для создания объектов из схемы XML и их использования в веб-сервисе Джерси. Я управляю версией веб-службы, и изменений достаточно для версии, но есть еще много кода, который можно использовать повторно. Использование интерфейсов оказалось проблематичным, поэтому я вместо этого использовал Groovy и переместил всю аналогичную логику в вышеупомянутый класс Groovy с утиным набором текста. Объекты в основном совпадают с некоторыми изменениями, поэтому утиная печать с интерфейсом для ввода в классе Java отлично работает.