2012-06-04 14 views
3

Я работаю над проектом со многими someInterface - someInterfaceImpl-pair. Несколько дней назад у меня появилась идея (возможно, вдохновленная чтением некоторого объектного кода c), чтобы включить реализацию по умолчанию в качестве внутреннего класса. Теперь некоторые коллеги (все с гораздо большим опытом java, чем я) увидели эту идею - обратная связь была шокирована и удивлена ​​(«это работает?»).Интерфейс с внутренней реализацией - хорошо или плохо

Я гугл вокруг немного, но не нашел много доказательств полезности этого «образца» (личный я люблю его): pdf-paper и a faq about code style

Что вы думаете - особенно в тех случаях, когда реализация «по умолчанию» тесно связана с интерфейсом.

Update я только что нашел это: Java Interface-Implementation Pair

(см принятый ответ)

ответ

8

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

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

Я думал, что этот пост дает интересное обсуждение подобного вопроса: Question

+3

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

+0

Я собирался добавить ответ о базовой реализации vs abstract vs interface, вы избили меня до него :-) – ptyx

+0

great minds ....;) cheers –

1

Я согласен с ответом выше, но есть некоторые случаи, когда в том числе реализации логично, как:

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

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

+0

True. Я изменил пример. –

+0

Опять же, интерфейс 'ModifyListener' не имеет реализации по умолчанию. Вы создали анонимный внутренний класс, который реализует интерфейс. –

1

Если реализация по умолчанию является достаточно тривиальной и, вероятно, оставаться таким образом, и если ничего не расширяет его, или, скорее всего, это, вероятно, путь. Вы не хотите помещать его в свой собственный файл, и где еще вы его положили? Я бы предложил сделать класс личное с общественным, например (не предполагая состояния):

/** An interface a lot like java.util.Collection. */ 
public interface WhatEver { 
    private class Default implements Whatever { 
     // Methods... 
    } 
    /** A default implementation that is always empty. Suitable as a NULL value. */ 
    public final WhatEver DEFAULT = new Default(); 
    // Rest of interface... 

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

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

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

Другим ключевым моментом является то, что вы не хотите слишком много кода в одном .java-файле, но вы тоже не хотите слишком малого.

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