2010-02-28 3 views
15

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

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

ответ

13

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

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

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

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

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

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

+0

Большое спасибо. Очень хороший ответ. Я не буду их использовать! –

+0

@ Мартин, спасибо, я добавил свой ответ, чтобы лучше объяснить. –

2

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

PS: заводной не мой язык, так что я на самом деле не знаю , можно ли определить интерфейсы там на всех.

5

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

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

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

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

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

+0

@ longshot какой IDE/язык вы используете с хорошим завершением метода? Я использую Netbeans с Ruby, и чаще всего он не знает, какие методы доступны, и просто завершает их из глобального пространства имен. –

+0

@yar например RubyMine –

+0

Squeak smalltalk имеет хороший метод завершения и браузер методов. AllegroCL имеет хорошую автозаполнение для Common Lisp. WingIDE имеет хорошее автозаполнение для Python, если он знает, какой тип вы ссылаетесь. XCode имеет хорошее завершение для ObjC, с тем же предостережением, что ему нужно знать тип, по которому вы отправляете сообщение. – longshot

1

В некоторых случаях да. У меня есть пример, где я создаю класс Groovy, который будет добавлен в класс 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 отлично работает.

Смежные вопросы