Должен ли я определить интерфейсы на языках Duck Typed? - PullRequest
15 голосов
/ 28 февраля 2010

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

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

Ответы [ 4 ]

13 голосов
/ 28 февраля 2010

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

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

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

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

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

Редактировать: Получил некоторую ясность от компьютера :) Одна из главных причин НЕ отделять интерфейс от реализации состоит в том, что вы уходите от зависимости от типов . Как вы знаете, при наборе утки меня не волнует, является ли он реализатором интерфейса Vehicle (например). Меня волнует только если у него есть go метод с 2 параметрами. Таким образом, чем больше вы работаете с интерфейсами, тем больше вы пишете Java на Groovy («вы можете писать на Фортране на любом языке»). Этого следует избегать, так как новые языки открывают вам новые возможности.

5 голосов
/ 28 февраля 2010

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

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

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

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

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

2 голосов
/ 28 февраля 2010

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

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

1 голос
/ 31 декабря 2014

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

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

Тогда отличная реализация выглядит так:

//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 работает отлично.

...