Существуют ли альтернативы ISomething / ISomethingable для интерфейсов? - PullRequest
11 голосов
/ 21 октября 2008

Стандарт .NET с префиксом имени интерфейса с I, кажется, становится широко распространенным и больше не ограничивается только .NET. Я сталкивался с большим количеством кода Java, который использует это соглашение (поэтому меня не удивит, если бы Java использовала его раньше, чем C #). Также Flex использует его и так далее. Размещение I в начале названия попахивает венгерской нотацией, и поэтому мне неудобно его использовать.

Итак, вопрос в том, существует ли альтернативный способ обозначения того, что Something является интерфейсом, а не классом, и есть ли необходимость в любом случае обозначать это так. Или это тот случай, когда он стал стандартом, и поэтому я должен просто принять его и перестать пытаться разжигать «религиозные войны», предлагая сделать это иначе?

Ответы [ 9 ]

19 голосов
/ 21 октября 2008

Из книги «Руководство по проектированию рамок»:

Интерфейсы, представляющие корни иерархии (например, IList), должны также использовать существительные или словосочетания. Интерфейсы, представляющие возможности, должны использовать прилагательные и прилагательные фразы (например, IComparable, IFormattable).

Также из аннотаций по именованию интерфейсов:

KRZYSZTOF CWALINA: один из немногих Используемые префиксы «I» для интерфейсов (как в ICollection), но это для исторические причины. Оглядываясь назад, я думаю, что было бы лучше использовать обычные имена типов. В большинстве разработчики кейсов не заботятся о том, что что-то интерфейс, а не абстрактный класс, например.

BRAD ABRAMS: С другой стороны, префикс «I» на интерфейсах признание влияния COM (и Java) в .NET Framework. COM популяризированный, даже институционализированный, нотация, что интерфейсы начинаются с «я». Хотя мы обсуждали отклоняясь от этой исторической картины мы решили перенести шаблон, как многие из наших пользователей были уже знаком с COM.

ДЖЕФФРИ РИХТЕР: Лично мне нравится «Я» префикс, и я хотел бы иметь больше такие вещи Маленький односимвольный префиксы имеют большое значение для сохранения код краткий и все же описательный. Насколько я сказал ранее, я использую префиксы для моего поля частного типа, потому что я нахожу это очень полезно.

BRENT RECTOR Примечание: это действительно другое применение Венгерская нотация (хотя одна без недостатки обозначений использовать в именах переменных).

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

16 голосов
/ 21 октября 2008

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

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

Один маленький момент данных: я работаю и с Java, и с C # изрядно, и мне регулярно приходится проверять, какие типы в Java на самом деле являются интерфейсами, особенно в рамках инфраструктуры сбора данных. .NET просто делает это простым. Может быть, это не беспокоит других людей, но это беспокоит меня.

+ 1 за IFoo от меня.

9 голосов
/ 21 октября 2008

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

С другой стороны, использование для клиента должно быть прозрачным, поэтому он не должен заботиться о подсказке этого типа. Кроме того, суффикс «able» в «Thingable» должен быть достаточно подсказкой. Это достаточно хорошо работает в Java.

/ EDIT: Я хотел бы отметить, что приведенные выше рассуждения побудили меня отказаться от префикса I для частных проектов. Однако, проверив одно из них по набору правил FxCop, я быстро вернулся к использованию I. Здесь выигрывает последовательность, , хотя глупая последовательность - это хобгоблин маленьких умов .

1 голос
/ 21 октября 2008

Все о стиле и удобочитаемости . Префикс интерфейсов с «I» - это просто соглашение об именах и руководство по стилю. Самим компиляторам все равно.

0 голосов
/ 01 августа 2013

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

  • Если у вас одно поведение и одна возможная реализация, просто не создавайте интерфейс:

    открытый класс StackOverflowAnswerGenerator {}

  • Если у вас одно поведение и много возможных реализаций, тогда проблем нет, и вы можете просто отбросить «I» и получить:

    открытый интерфейс StackOverflowAnswerGenerator {}

    открытый класс StupidStackOverflowAnswerGenerator: StackOverflowAnswerGenerator {}

    открытый класс RandomStackOverflowAnswerGenerator: StackOverflowAnswerGenerator {}

    открытый класс GoogleSearchStackoverflowAnswerGenerator: StackOverflowAnswerGenerator {}

    // ...

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

    a) Префикс или суффикс реализации (как указано в некоторых других ответах в этом разделе)

    b) Использовать другое пространство имен для интерфейса:

    namespace StackOverflowAnswerMachine.Interfaces { открытый интерфейс StackOverflowAnswerGenerator {} }

    namespace StackOverflowAnswerMachine { открытый класс StackOverflowAnswerGenerator: Interfaces.StackOverflowAnswerGenerator {} }

    c) Используйте другое пространство имен для реализации:

    namespace StackOverflowAnswerMachine { открытый интерфейс StackOverflowAnswerGenerator {} }

    namespace StackOverflowAnswerMachine.Implementations { открытый класс StackOverflowAnswerGenerator: StackOverflowAnswerMachine.StackOverflowAnswerGenerator {} }

В настоящее время я экспериментирую с последней возможностью. Обратите внимание, что в исходном файле реализации у вас все еще может быть «using StackOverflowAnswerMachine;» и иметь удобный доступ к объектам домена.

ОБНОВЛЕНИЕ: Несмотря на то, что я все еще думаю, что последняя возможность является самой чистой, ее недостатком является то, что, хотя "с помощью StackOverflowAnswerMachine;" дает вам доступ ко всем объектам домена, вы должны использовать префикс всех интерфейсов домена, чтобы не путать их реализации. Это может показаться чем-то не очень удобным, но в чистом дизайне обычно класс не использует много других доменных объектов, и в основном вам нужно использовать префикс только в объявлении поля и списке параметров конструктора. Итак, это моя текущая рекомендация.

Клиент функциональности домена не должен знать, использует ли он интерфейс, абстрактный класс или конкретный класс. Если им нужно это знать, то в таком проекте есть серьезная проблема, потому что в одном и том же уровне абстракции смешаны логика предметной области и инфраструктурные проблемы. Поэтому я рекомендую решения " a " или " c ".

0 голосов
/ 01 апреля 2009

Вы попросили альтернативу, поэтому вот одна, с которой я столкнулся:

Используйте префикс no в классе интерфейса, но используйте префикс c или C в соответствующих конкретных классах. Большая часть вашего кода обычно ссылается на интерфейс, поэтому зачем загрязнять его префиксом, а не обычно менее используемым конкретным типом.

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

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

0 голосов
/ 05 января 2009

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

public class CustomerImpl implements Customer
0 голосов
/ 21 октября 2008

Для .NET книга Microsoft Framework Design Guidelines абсолютно рекомендует это, и да, она очень стандартная. Я никогда не видел, чтобы это было сделано иначе, и создание нового соглашения могло бы только сбить людей с толку.

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

0 голосов
/ 21 октября 2008

Стандарт кодирования для Symbian имеет интерфейсы (чисто абстрактные классы C ++), обозначенные буквой M, а не I.

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

...