Совершенный код. Совершенный код. Мастер-класс. Стив Макконнелл. Руководство по стилю программирования и конструированию по
Скачать 5.88 Mb.
|
ГЛАВА 11 Сила имен переменных 267 Идентифицируйте неизменяемые параметры, если язык не требует их явного определения Иногда программисты случайно изменяют входные пара# метры. C++, Visual Basic и некоторые другие языки заставляют явно указывать, хотите ли вы, чтобы изменения параметров внутри метода были доступны в остальном коде. Для этого служат спецификаторы *, & и const в C++ и ByRef/ByVal в Visual Basic. В случае других языков изменение входной переменной в методе отражается в остальном коде, хотите вы того или нет. Это особенно верно при передаче объектов. Например, в Java все объекты передаются в методы «значением», поэтому, пере# давая объект в метод, будьте готовы к тому, что состояние объекта может изме# ниться 1 (Arnold, Gosling, Holmes, 2000). Если, программируя на таком языке, вы следуете конвенции именования, согласно которой исключительно входные (неизменяемые) параметры нужно дополнять префиксом const (или final, или nonmodifiable, или каким#то аналогич# ным), то, увидев что#то с префиксом const слева от знака равенства, вы будете знать, что произошла ошибка. Если вы увидите вызов constMax.SetNewMax( ... ), вы также по префиксу const поймете, что это ошибка. Форматируйте имена так, чтобы их было легко читать Для повышения удобочитаемости кода слова в именах переменных часто разделяют заглавными буквами или символами#разделителями. Например, имя GYMNASTICSPOINTTOTAL читается хуже, чем gymnasticsPointTotal или gymnastics_point_total. C++, Java, Visual Basic и другие языки позволяют использовать оба этих подхода. Старайтесь не смешивать эти способы, так как это осложняет чтение кода. Если же вы будете согласованно использовать один из подходов, код станет более по# нятным. Программисты уже давно спорят по поводу того, делать ли заглавной первую букву имени ( TotalPoints или totalPoints), но если все участвующие в про# екте программисты будут поступать согласованно, подобные мелочи не будут играть особой роли. В данной книге имена переменных начинаются с буквы нижнего регистра по той причине, что этот подход принят в языке Java, а также для под# держания сходства стилей между разными языками. Конвенции, специфические для конкретных языков Соблюдайте конвенции именования, принятые в используемом вами языке. Книги по стилю программирования можно найти почти для любого языка. Советы, отно# сящиеся к языкам C, C++, Java и Visual Basic, даны в следующих подразделах. Конвенции C Конвенции именования, используемые при программировании на C, предпола# гают, что: имена символьных переменных дополняются префиксом c или ch; целочисленным индексам присваиваются имена i и j; Перекрестная ссылка Дополне- ние языка конвенцией именова- ния, компенсирующей ограниче- ния самого языка, является при- мером программирования с ис- пользованием языка вместо простого программирования на языке (см. раздел 34.4). 1 Значением передается ссылка на объект, который и может быть изменен. — Прим. перев. 268 ЧАСТЬ III Переменные имена переменных, хранящих количество чего#либо, до# полняются префиксом n; имена указателей дополняются префиксом p; имена строк начинаются с префикса s; имена макросов препроцессора включают ТОЛЬКО_ЗАГ% ЛАВНЫЕ_БУКВЫ; обычно это правило распространяется и на имена типов, определяемых при помощи директивы typedef; имена переменных и методов включают только_строчные_буквы; для разделения слов служит символ подчеркивания (_): имена_такого_вида читаются легче, чем именатакоговида. Эти правила справедливы для программирования на C в общем, а также для сред UNIX и Linux, однако в разных средах конвенции имеют свои особенности. Про# граммисты на C, разрабатывающие программы для Microsoft Windows, предпочи# тают применять для именования переменных ту или иную форму венгерской нотации и буквы верхнего и нижнего регистров. Программисты, разрабатываю# щие ПО для платформы Macintosh, обычно используют для именования методов смешанный регистр, потому что инструментарий Macintosh и методы ОС были изначально разработаны в соответствии с интерфейсом Pascal. Конвенции C++ С программированием на C++ связаны такие конвенции: целочисленным индексам присваиваются имена i и j; имена указателей дополняются префиксом p; имена констант, типов, определяемых с помощью дирек# тивы typedef, и макросов препроцессора включают ТОЛЬКО_% ЗАГЛАВНЫЕ_БУКВЫ; имена классов и других типов содержат БуквыОбоихРегистров; первое слово в именах переменных и методов начинается со строчной буквы, а все последующие слова — с заглавной: имяПеременнойИлиМетода; символ подчеркивания используется только в именах, состоящих полностью из заглавных букв, и после некоторых префиксов (например, после префикса, служащего для идентификации глобальных переменных). Как и в случае языка C, некоторые аспекты этой конвенции могут зависеть от конкретной среды. Конвенции Java В отличие от C и C++ конвенции стиля программирования на Java были сформулированы уже на ранних этапах раз# вития этого языка: i и j — имена целочисленных индексов; имена констант включают ТОЛЬКО_ЗАГЛАВНЫЕ_БУКВЫ, а слова разделяются символами подчеркивания; Дополнительные сведения Классической книгой о стиле программирования на C являет- ся «C Programming Guidelines» (Plum, 1984). Дополнительные сведения О стиле программирования на C++ см. книгу «The Elements of C++ Style» (Misfeldt, Bumgardner, and Gray, 2004). Дополнительные сведения О сти- ле программирования на Java см. книгу «The Elements of Java Style, 2d ed.» (Vermeulen et al., 2000). ГЛАВА 11 Сила имен переменных 269 все слова в именах классов и интерфейсов начинаются с заглавной буквы: ИмяКлассаИлиИнтерфейса; в именах переменных и методов с заглавной буквы начинаются все слова, кроме первого: имяПеременойИлиМетода; символ подчеркивания служит разделителем только в именах, полностью со# стоящих из заглавных букв; имена методов доступа начинаются с префикса get или set. Конвенции Visual Basic Устойчивых конвенций стиля программирования на Visual Basic не существует. Чуть ниже я приведу один из возможных вариантов. Программирование с использованием нескольких языков Если вы программируете, используя несколько языков, сформулируйте конвенцию именования (а также форматирования, документирования и т. д.) так, чтобы она способствовала общей согласованности и удобочитаемости кода, даже если для этого придется отступить от конвенции, принятой в одном из языков. Например, в этой книге все имена переменных начинаются со строчной буквы, что соответствует конвенции Java и некоторым, но не всем конвенциям C++. Все имена методов начинаются с заглавной буквы, что согласуется с конвенцией C++. Согласно конвенции Java имена методов должны были бы начинаться с буквы нижнего регистра, но ради общей удобочитаемости я решил независимо от язы# ка начинать их с заглавной буквы. Примеры конвенций именования В стандартных конвенциях, описанных выше, не отражены некоторые важные аспекты, в том числе область видимости переменных (закрытая, класс или гло# бальная), различия имен классов и объектов, методов и переменных и т. д. Советы по именованию могут показаться сложными, если они сконцентрирова# ны на нескольких страницах. Однако на самом деле они могут быть вполне про# стыми, и вы можете адаптировать их к своим потребностям. Имена переменных должны включать информацию трех видов: суть переменной (то, что переменная представляет); тип данных (именованная константа; элементарная переменная; тип, опреде# ленный пользователем, или класс); область видимости переменной (закрытая, класс, пакет или глобальная область видимости). В табл. 11#3, 11#4 и 11#5 описаны конвенции именования для языков C, C++, Java и Visual Basic, основанные на уже известных вам принципах. Использовать имен# но эти конвенции не обязательно, однако они помогут вам понять, что может включать неформальная конвенция именования. 270 ЧАСТЬ III Переменные Табл. 11-3. Пример конвенции именования для языков C++ и Java Сущность Описание ClassName Имена классов начинаются с заглавной буквы и включают буквы обоих регистров. TypeName Имена типов, в том числе перечислений и типов, определяе# мых при помощи директив typedef, начинаются с заглавной буквы и включают буквы обоих регистров. EnumeratedTypes Кроме предыдущего правила, имена перечислений всегда име# ют форму множественного числа. localVariable Имена локальных переменных начинаются со строчной буквы и включают буквы обоих регистров. Имя должно характеризо# вать сущность, представляемую переменной, и не должно зави# сеть от фактического типа переменной. routineParameter Имена параметров методов форматируются так же, как имена локальных переменных. RoutineName() Имена методов включают буквы обоих регистров (об удачных именах методов см. раздел 7.3). m_ClassVariable Имена переменных#членов, доступных только методам класса, дополняются префиксом m_. g_GlobalVariable Имена глобальных переменных дополняются префиксом g_. CONSTANT Имена именованных констант включают ТОЛЬКО_ЗАГЛАВ% НЫЕ_БУКВЫ. MACRO Имена макросов включают ТОЛЬКО_ЗАГЛАВНЫЕ_БУКВЫ. Base_EnumeratedType Имена элементов перечислений дополняются именем самого перечисления в единственном числе: Color_Red, Color_Blue. Табл. 11-4. Пример конвенции именования для языка C Сущность Описание TypeName Имена типов начинаются с заглавной буквы и включают буквы обоих регистров. GlobalRoutineName() Имена открытых методов включают буквы обоих регистров. f_FileRoutineName() Имена методов, видимых в одном модуле (файле), дополняются префиксом f_. LocalVariable Имена локальных переменных включают буквы обоих регист# ров. Имя должно характеризовать сущность, представляемую переменной, и не должно зависеть от фактического типа переменной. RoutineParameter Имена параметров методов форматируются так же, как имена локальных переменных. f_FileStaticVariable Имена переменных, видимых в одном модуле (файле), дополня# ются префиксом f_. G_GLOBAL_Glo% Имена глобальных переменных дополняются префиксом G_ и balVariable обозначением модуля (файла), в котором определена перемен# ная; обозначение модуля (файла) включает только заглавные буквы: SCREEN_Dimensions. ГЛАВА 11 Сила имен переменных 271 Табл. 11-4. (окончание) Сущность Описание LOCAL_CONSTANT Имена именованных констант, видимых в одном методе или модуле (файле), включают только заглавные буквы: ROWS_MAX. G_GLOBALCONSTANT Имена глобальных именованных констант включают только заглавные буквы и дополняются префиксом G_ и обозначением модуля (файла), в котором определена именованная константа; обозначение модуля (файла) включает только заглавные буквы: G_SCREEN_ROWS_MAX. LOCALMACRO() Имена макросов, видимых в одном методе или модуле (файле), включают только заглавные буквы. G_GLOBAL_MACRO() Имена глобальных макросов включают только заглавные буквы и дополняются префиксом G_ и обозначением модуля (файла), в котором определен макрос; обозначение модуля (файла) включает только заглавные буквы: G_SCREEN_LOCATION(). Так как Visual Basic безразличен к регистру букв, для различения имен типов и переменных приходится применять специфические правила (табл. 11#5). Табл. 11-5. Пример конвенции именования для языка Visual Basic Сущность Описание C_ClassName Имена классов дополняются префиксом C_, начинаются с заглавной буквы и включают буквы обоих регистров. T_TypeName Имена типов дополняются префиксом T_, начинаются с заглавной буквы и включают буквы обоих регистров. T_EnumeratedTypes Кроме предыдущего правила, имена перечислений всегда имеют форму множественного числа. localVariable Имена локальных переменных начинаются со строчной буквы и включают буквы обоих регистров. Имя должно характеризо# вать сущность, представляемую переменной, и не должно зави# сеть от фактического типа переменной. routineParameter Имена параметров методов форматируются так же, как имена локальных переменных. RoutineName() Имена методов включают буквы обоих регистров (об удачных именах методов см. раздел 7.3). m_ClassVariable Имена переменных#членов, доступных только методам класса, дополняются префиксом m_. g_GlobalVariable Имена глобальных переменных дополняются префиксом g_. CONSTANT Имена именованных констант включают ТОЛЬКО_ЗАГЛАВНЫЕ_БУКВЫ. Base_EnumeratedType Имена элементов перечислений дополняются именем самого перечисления в единственном числе: Color_Red, Color_Blue. 272 ЧАСТЬ III Переменные 11.5. Стандартизованные префиксы Стандартизация префиксов обеспечивает лаконичный, но в то же время согласованный и понятный способ именова# ния данных. Самая известная схема стандартизации префик# сов — венгерская нотация — представляет собой набор де# тальных принципов именования переменных и методов (а не жителей Венгрии!) , который когда#то широко применялся при программи# ровании для ОС Microsoft Windows. Сейчас венгерскую нотацию используют ред# ко, но ее суть — создание стандартизованного набора лаконичных точных абб# ревиатур — от этого не становится менее полезной. Стандартизованный префикс состоит из двух частей: аббревиатуры типа, опреде# ленного пользователем (user#defined type, UDT), и семантического префикса. Аббревиатура типа, определенного пользователем Аббревиатура UDT обозначает тип объекта или переменной. Как правило, аббреви# атуры UDT служат для описания таких сущностей, как окна, области экрана и шриф# ты, но не предопределенных типов данных конкретного языка программирования. Типы UDT описываются краткими кодами, которые вы создаете и стандартизиру# ете для конкретной программы. Коды — это мнемонические обозначения, такие как wn в случае окна и scr в случае области экрана. В табл. 11#6 приведены при# меры UDT, которые можно было бы задействовать в текстовом редакторе. Табл. 11-6. Примеры UDT текстового редактора Аббревиатура UDT Значение ch Символ (тип данных, используемый для представления символа документа, а не символ C++) doc Документ pa Абзац (paragraph) scr Область экрана sel Выбранный текст wn Окно При работе с UDT следует также определить типы данных с именами, соответству# ющими аббревиатурам UDT. Таким образом, при использовании UDT из табл. 11#6 у вас получились бы подобные объявления данных: CH chCursorPosition; SCR scrUserWorkspace; DOC docActive PA firstPaActiveDocument; PA lastPaActiveDocument; WN wnMain; Разумеется, аббревиатуры следует создавать для тех UDT, которые чаще всего встре# чаются в конкретной среде. Дополнительные сведения О венгерской нотации см. статью «The Hungarian Revolution» (Si- monyi and Heller, 1991). ГЛАВА 11 Сила имен переменных 273 Семантические префиксы Семантические префиксы дополняют аббревиатуры UDT, характеризуя использо# вание переменной или объекта. В отличие от аббревиатур UDT, зависимых от конкретного проекта, семантические префиксы являются в некотором смысле стандартными (табл. 11#7). Табл. 11-7. Семантические префиксы Семантический префикс Значение c Количество (записей, символов и т. д.). first Элемент массива, обрабатываемый первым. Префикс first аналогичен префиксу min, но связан с текущей операцией, а не с самим массивом. g Глобальная переменная. i Индекс массива. last Элемент массива, обрабатываемый последним. Префикс last дополняет префикс first. lim Верхняя граница обрабатываемого массива. Значение с пре# фиксом lim уже не является допустимым индексом. Как и last, префикс lim дополняет префикс first. В отличие от префикса last, используемого для представления последнего допустимого элемента, значение с lim выходит за пределы массива. В общем, lim равняется last + 1. m Переменная уровня класса. max Индекс последнего элемента массива или другого списка. Префикс max связан с самим массивом, а не с выполняемыми над массивом операциями. min Индекс первого элемента массива или другого списка. p Указатель. Семантические префиксы включают строчные буквы или буквы обоих регистров и по мере необходимости объединяются с аббревиатурами UDT и другими семанти# ческими префиксами. Например, имя переменной, определяющей первый абзац документа, включило бы аббревиатуру pa, говорящую о том, что это абзац, и пре# фикс first, показывающий, что это первый абзац. В итоге мы получили бы имя firstPa. Индекс набора абзацев был бы назван iPa; счетчик или число абзацев — cPa, а первый и последний абзацы текущего активного документа — firstPaActiveDocument и lastPaActiveDocument соответственно. Достоинства стандартизованных префиксов Стандартизованные префиксы обеспечивают все общие преимущества конвенций именования, а также некоторые дополнительные. Стандарти# зация имен снижает число имен элементов программы или класса, ко# торые нужно помнить. Стандартизованные префиксы позволяют уточнить имена, которые без этого ча# сто оказываются неточными. Особенно полезны точные различия между префик# сами min, first, last и max. 274 ЧАСТЬ III Переменные Стандартизованные префиксы делают имена более компактными. Так, переменной, определяющей число абзацев, можно присвоить имя cpa, а не totalParagraphs. Ин# декс массива абзацев можно назвать ipa, а не indexParagraphs или paragraphsIndex. Наконец, стандартизованные префиксы облегчают проверку правильности исполь# зования абстрактных типов данных, когда компилятор оказывается беспомощным. Так, выражение paReformat = docReformat скорее всего ошибочно, потому что аб# бревиатуры pa и doc соответствуют разным UDT. Главная ловушка при использовании стандартизованных префиксов — отказ от дополнения префикса выразительным именем переменной. Так, если имя ipa од# нозначно определяет индекс массива абзацев, есть соблазн не присваивать пере# менной более выразительное имя, такое как ipaActiveDocument. Помните про удо# бочитаемость кода и присваивайте переменным описательные имена. 11.6. Грамотное сокращение имен переменных Стремление к сокращению имен переменных в некотором смысле ста# ло пережитком. В более старых языках, таких как ассемблер, обычный Basic и Fortran, имена переменных были ограничены 2–8 символами. Кроме того, раньше программирование было более тесно связано с математикой, что побуждало использовать в уравнениях и других выражениях переменные с «ма# тематическими» именами i, j, k и т. п. C++, Java, Visual Basic и другие современные языки позволяют создавать имена почти любой длины, поэтому сокращение вы# разительных имен уже не имеет под собой практически никаких оснований. Если обстоятельства требуют создания коротких имен, помните, что некоторые способы сокращения имен лучше других. Удачные короткие имена можно создать, устранив ненужные слова, выбрав более короткие синонимы и использовав ка# кую#нибудь из нескольких стратегий сокращения. Целесообразно знать несколь# ко методик сокращения имен, потому что ни одна из них не является одинаково эффективной во всех случаях. Общие советы по сокращению имен Ниже я привел несколько рекомендаций по сокращению имен. Некоторые из них противоречат другим, так что не пытайтесь использовать все советы сразу. Итак: используйте стандартные аббревиатуры (общепринятые, которые можно найти в словаре); удаляйте все гласные, не являющиеся первыми буквами имен ( computer — cmptr, screen — scrn, apple — appl, integer — intgr); удаляйте артикли и союзы, такие как and, or, the и т. д.; сохраняйте одну или несколько первых букв каждого слова; «обрезайте» слова согласованно: после первой, второй или третьей буквы (вы# бирайте вариант, уместный в конкретном случае); сохраняйте первую и последнюю буквы каждого слова; сохраняйте до трех выразительных слов; удаляйте бесполезные суффиксы: ing, ed и т. д. |