Подтвердить что ты не робот

Соглашение об именах интерфейсов

Это, конечно, субъективная вещь, но я не вижу ничего позитивного в префиксах имен интерфейса с "я". Для меня Thing практически всегда читается, чем IThing.

Мой вопрос в том, почему это соглашение существует? Несомненно, это упрощает передачу интерфейсов из других типов. Но разве этот аргумент не будет распространяться на сохранение венгерской нотации, которая теперь широко осуждается?

Какой ваш аргумент для этого неудобного "я"? Или, что еще более важно, что может быть Microsoft?

4b9b3361

Ответ 1

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

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

  • Интерфейсы имеют префикс I, чтобы отличать его от абстрактных классов. Существует двусмысленность, когда вы видите следующий код:

    public class Apple: Fruit

    Без соглашения никто не знал бы, что Apple наследуется от другого класса с именем Fruit, или если это была реализация интерфейса с именем Fruit, тогда как IFruit сделает это очевидным:

    public class Apple: IFruit

    Принцип наименьшего удивления применяется.

  • Не все использование венгерской нотации осуждаются. Раннее использование венгерской нотации означало префикс, указывающий тип объекта, а затем имя переменной или иногда подчеркивание до имя переменной. Это было для определенных программных сред (думаю, Visual Basic 4 - 6) полезно, но по мере того, как популярное объектно-ориентированное программирование стало популярным, стало непрактичным и излишним указать тип. Это стало особенно актуальным, когда дело дошло до intellisense.

    Сегодня венгерская нотация приемлема для того, чтобы отличать элементы пользовательского интерфейса от фактических данных и аналогично связанных элементов пользовательского интерфейса, например txtObject для текстового поля, lblObject для метки, связанной с этим текстовым полем, тогда как данные для текстового поля просто Object.

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

Ответ 2

Ну, одно очевидное соображение было бы (очень распространенная) пара IFoo и Foo (при абстрагировании Foo), но в целом часто важно знать, является ли что-то интерфейсом vs class. Да, это частично избыточно, но ИМО отличается от таких вещей, как sCustomerName - здесь само имя (customerName) должно быть достаточным для понимания переменной.

Но с CustomerRepository - это что класс или абстрактный интерфейс?

Также: ожидание; факт, правильный или неправильный, то, что люди ожидают. Это достаточно почти.

Ответ 3

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

Ответ 4

Thing является более читаемым именем, чем IThing. Я из школы мысли, что мы должны программировать интерфейсы, а не конкретные реализации. В общем случае интерфейсы должны иметь приоритет над реализациями. Я предпочитаю давать более читаемое имя для интерфейса, а не для реализации (т.е. Мои интерфейсы называются без префикса "I" ).

Ответ 5

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

Ответ 6

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

Ответ 7

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

Ответ 8

Я уверен, что ваш вопрос был темой многих длительных обсуждений в команде Microsoft, которые работали над .NET Framework и ее стандартами.

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

От Krzysztof Cwalina, руководитель программы CLR:

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

От менеджера программ Brad Abrams, CLR и .NET Framework:

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

От Джеффри Рихтера, консультант и автор:

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

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

Лично - и, возможно, по привычке - мне нравится префикс I, потому что он красновато флажками интерфейсов, позволяя мне иметь индивидуальное соответствие имен с типами реализации. Это сияет в случаях, когда вы хотите реализовать реализацию base: IThing - это интерфейс, Thing - это базовый (возможно, abstract) тип. Производные типы могут быть SomeThing. Мне нравится использовать такие кристально чистые сокращения.

Ответ 9

Потому что у вас обычно есть IThing и Thing. Поэтому вместо того, чтобы позволить людям приходить со своими "конвенциями" для этой повторяющейся ситуации, был выбран единый единообразный вариант для всех конвенций. Повторяя то, что говорят другие, фактическая стандартность является достаточной причиной для ее использования.

Ответ 10

Введите имена интерфейса префикса с помощью буквы I, чтобы указать, что тип интерфейс.

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

Что вам нужно получить, сбросив префикс I?

Ответ 11

Это просто соглашение, целью которого является предотвращение конфликтов имен. С# не позволяет мне иметь класс и интерфейс с именем Client, даже если имена файлов - это Client и IClient, соответственно. Мне удобно использовать конвенцию; если бы мне пришлось предложить другое соглашение, я бы предложил использовать "Контракт" в качестве суффикса, например. ClientContract.

Ответ 12

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

Соглашение об именах, которое будет больше в строке остальной части фреймворка, будет включать тип в имени, например классы xxxAttribute и xxxException, что делает его xxxInterface. Это немного длиннее, хотя, и все интерфейсы - это нечто отдельное, а не просто еще одна группа классов.

Ответ 13

Отделить интерфейсы от классов.

Также (это скорее личное наблюдение, чем продиктованное с высокой), интерфейсы описывают, что делает класс. "Я" поддался этому (я уверен, что это построение в грамматике, которое было бы здорово выскочить прямо сейчас); интерфейс, который описывает классы, которые проверяют, будет "Ивалити". Одним из них, описывающим соответствие поведения, является "IMatch".

Ответ 14

Он выглядит Hungarian для меня. Венгерский вообще считается угрозой на строго типизированных языках.

Так как С# является продуктом Microsoft, а венгерская нотация была изобретением Microsoft, я могу видеть, где С# может быть восприимчив к ее влиянию.

Ответ 15

Я знаю, что в рекомендациях Microsoft рекомендуется использовать "я", чтобы описать его как интерфейс. Но это происходит из соглашений об именах IBM, если я не ошибаюсь, инициализируя "I" для интерфейсов и последующий * Impl для реализации.

Однако, на мой взгляд, соглашения о присвоении имен Java являются лучшим выбором, чем соглашение об именах IBM (и не только в Java, для С# и любом языке программирования OO). Интерфейсы описывают, что объект может сделать, если он реализует интерфейс, а описание должно быть в форме глагола. I.e Runnable, Serializable, Invoiceable и т.д. IMHO - это идеальное описание того, что представляет интерфейс.

Ответ 16

Для графического интерфейса ОС очень популярно использовать разные значки для файлов и папок. Если все они имеют одинаковые значки, но папки с префиксом "F", было бы приемлемо использовать один и тот же значок. Но, поскольку скорость распознавания изображений людей быстрее скорости распознавания слов, мы установили иконки.

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

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

Ответ 17

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

Ни "Fruit", ни "IFruit" не имели бы для меня большого значения как интерфейс. Это связано с тем, что он намного больше похож на класс. Классы определяют вещи, тогда как интерфейсы должны определять функциональность.

Соглашение о присвоении имен "I" помогает различать классы и интерфейсы, поэтому разработка немного проще. И хотя это не требуется, это, безусловно, помогает избежать общих объектно-ориентированных головных болей. С#, как Java, допускает только наследование из одного базового класса. Но вы можете реализовать столько интерфейсов, сколько хотите. Предостережение заключается в том, что если вы наследуете класс и реализуете один или несколько интерфейсов, базовый класс должен быть назван первым (то есть класс Trout: Fish, ISwimmer, IDiver...).

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

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

Интерфейсы, которые определяют неодушевленные объекты (т.е. вещи, которые не могут действовать сами по себе)... Мне нравится называть их... способными в конце IPrintable (например, документ, счет-фактура) IPlayable (например, Instrument, MediaPlayer) ISavable (например, документ, изображение) IEdible (например, фрукты, говядина) IDrivable (например, автомобиль) IFlyable (например, Plane)

Интерфейсы, которые определяют одушевленные объекты (т.е. вещи, которые действуют сами по себе)... Мне нравится называть их... er в конце ISwimer (например, рыба, собака, утка) IDiver (например, Fish, Duck) IFlyer (например, Pilot) IDriver (например, NascarDriver)

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

Ответ 18

Дело в том, что все это понимают, а часть написания лучшего кода упрощает чтение и понимание.

Ответ 19

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

Мне нравится иметь интерфейс, описывающий, что интерфейс делает как можно более общий, например, Validator. Конкретной реализацией, которая проверяет конкретную вещь, будет ThingValidator, а реализация с некоторой абстрактной функциональностью, разделяемой Validator, будет AbstractValidator. Я бы сделал это, даже если Thing является единственным... ну... вещью, которую я проверяю, и Validator будет общим.

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

Ответ 20

Вы можете добавить слово "интерфейс" в качестве суффикса в свой настраиваемый интерфейс, например "SerializerInterface". Для абстрактного класса "Фрукты", например, "FruitAbstract", или вы можете сделать его "AbstractFruit", просто быть последовательным на всем протяжении. Это достаточно читаемо или соответствует обычным соглашениям об именах.

Ответ 21

Только мои 2 цента:

Причина, по которой я лично добавляю суффикс "Интерфейс", заключается в том, что его легче читать, чем префикс "I", и потому, что файлы в системе перечислены "сгруппированы". Например:

Не очень хорошо:

Alien.php
Host.php
IAlien.php
IHost.php
IXenomorph.php
Xenomorph.php

лучше:

Alien.php
AlienInterface.php
Host.php
HostInterface.php
Xenomorph.php
XenomorphInterface.php

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