Когда я должен возвратить Интерфейс и когда реальный класс?

Я боролся с этим весь уик-энд и наконец решил это. Оказывается, что php.ini указывает на несуществующий «каталог расширений». Создайте файл phpinfo () и посмотрите значение этого поля: extensions_dir

Я заметил, что в установленной папке mamp php есть папка no-debug-non-zts-20131226 который отличается от значения, показанного в phpinfo (). Я сделал клонирование этой папки и изменил имя на значение phpinfo (). Возможно, вы могли бы изменить файл php.ini, но я не хотел.

Я не знаю, решили ли вы свою проблему, но я публикую это, потому что моя проблема была другой, и Google взял меня сюда, поэтому я надеюсь помочь будущим гуглерам, имеющим аналогичную проблему.

Надеюсь, это поможет.

22
задан Robert Harvey 5 July 2011 в 20:35
поделиться

11 ответов

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

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

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

Тем не менее, ваш пример пахнет преждевременной оптимизацией.

Если метод является или может быть критическим, он может упомянуть детали реализации в документации.

9
ответ дан 29 November 2019 в 03:32
поделиться

Вернуть соответствующий интерфейс, чтобы скрыть детали реализации. Ваши клиенты должны заботиться только о том, что предлагает ваш объект, а не о том, как вы его реализовали. Если вы начнете с частного ArrayList и позже решите, что что-то еще (например, LinkedLisk, список пропуска и т. Д.) Более подходит, вы можете изменить реализацию, не затрагивая клиентов, если вы вернете интерфейс. В тот момент, когда вы возвращаете конкретный тип, возможность теряется.

30
ответ дан 29 November 2019 в 03:32
поделиться

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

7
ответ дан 29 November 2019 в 03:32
поделиться

Как правило, для общедоступного интерфейса, такого как API, возврат интерфейса (например, List ) поверх конкретной реализации (например, ArrayList ) было бы лучше.

Использование ArrayList или LinkedList - это деталь реализации библиотеки, которую следует учитывать в наиболее распространенном варианте использования этой библиотеки. И, конечно, внутренне наличие частных методов, передающих LinkedList s, не обязательно будет плохим делом, если оно предоставляет средства, облегчающие обработку.

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

Сама библиотека должна быть черным ящиком для своих потребителей, поэтому им не нужно беспокоиться о том, что происходит внутренне. Это также означает, что библиотека должна быть спроектирована так, чтобы ее можно было использовать так, как она задумана.

6
ответ дан 29 November 2019 в 03:32
поделиться

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

В этом контексте я бы ответил , возвращайте только то, что имеет смысл . Имеет ли вообще смысл возвращаемое значение быть конкретным классом? В вашем примере спросите себя: будет ли кто-нибудь использовать специфичный для LinkedList метод для возвращаемого значения foo?

  • Если нет, просто используйте интерфейс более высокого уровня. Он гораздо более гибкий и позволяет вам изменять бэкэнд
  • . Если да, спросите себя: нельзя ли рефакторировать свой код, чтобы вернуть интерфейс более высокого уровня? :)

Чем более абстрактен ваш код, тем меньше изменений вам потребуется при изменении бэкэнда. Это так просто.

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

7
ответ дан 29 November 2019 в 03:32
поделиться

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

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

4
ответ дан 29 November 2019 в 03:32
поделиться

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

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

4
ответ дан 29 November 2019 в 03:32
поделиться

You'll find (or have found) that as you return interfaces, they permeate through your code. e.g. you return an interface from method A and you have to then pass an interface to method B.

What you're doing is programming by contract, albeit in a limited fashion.

This gives you enormous scope to change implementations under the covers (provided these new objects fulfill the existing contracts/expected behaviours).

Given all of this, you have benefits in terms of choosing your implementation, and how you can substitute behaviours (including testing - using mocking, for example). In case you hadn't guessed, I'm all in favour of this and try to reduce to (or introduce) interfaces wherever possible.

0
ответ дан 29 November 2019 в 03:32
поделиться

Не имеет большого значения, возвращает ли метод API интерфейс или конкретный класс; несмотря на то, что здесь все говорят, вы почти никогда не меняете класс реализации после написания кода.

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

3
ответ дан 29 November 2019 в 03:32
поделиться

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

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

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

IParser parser = new Parser();

Теперь IParser будет вашим интерфейсом, а Parser - вашей реализацией. Теперь, когда вы работаете с объектом синтаксического анализатора сверху, вы будете работать против интерфейса (IParser), который, в свою очередь, будет работать против вашей реализации (Parser).

Это означает, что вы можете изменить внутреннюю работу Parser на столько, сколько вы хотите,

1
ответ дан 29 November 2019 в 03:32
поделиться

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

Что касается использования кода, Майкл выше прав в том, что быть как можно более универсальным в параметрах метода часто даже важнее. Это особенно верно при тестировании такого метода.

1
ответ дан 29 November 2019 в 03:32
поделиться
Другие вопросы по тегам:

Похожие вопросы: