Добавил:
Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
книги хакеры / Питер_Гудлиф_Ремесло_программиста_Практика_написания_хорошего_кода.pdf
Скачиваний:
15
Добавлен:
19.04.2024
Размер:
9.23 Mб
Скачать

 

 

 

 

hang

e

 

 

 

 

 

 

 

C

 

E

 

 

 

 

X

 

 

 

 

 

 

-

 

 

 

 

 

d

 

 

F

 

 

 

 

 

 

t

 

 

D

 

 

 

 

 

 

 

i

 

 

 

 

 

 

 

 

 

r

 

P

 

 

 

 

 

NOW!

o

 

 

 

 

 

 

 

 

 

 

 

 

 

BUY

 

 

 

 

 

 

to

 

 

 

 

 

w Click

 

 

 

Техническиеm

подробности

 

 

 

 

w

 

 

 

 

 

 

 

 

 

 

w

 

 

 

 

 

 

 

o

 

 

.

 

 

 

 

 

.c

 

 

 

p

 

 

 

 

g

 

 

 

 

 

df

 

 

n

e

 

 

 

 

 

-xcha

 

 

 

 

Технические подробности

 

 

 

 

hang

e

 

 

 

 

 

 

 

C

 

E

 

 

 

 

X

 

 

 

 

 

 

-

 

 

 

 

 

d

 

 

F

 

 

 

 

 

 

t

 

 

D

 

 

 

 

 

 

 

i

 

 

 

 

 

 

 

 

 

r

P

 

 

 

 

 

NOW!

o

 

 

 

 

 

 

 

 

 

 

 

 

BUY

 

 

 

 

 

 

to

 

 

 

 

 

79Click

 

 

 

 

 

m

 

 

 

 

 

 

w

 

 

 

 

 

 

 

o

 

 

w

 

 

 

 

 

 

 

 

w

 

 

 

 

 

 

.c

 

 

.

 

 

 

 

 

 

 

 

p

 

 

 

 

g

 

 

 

 

 

df

 

 

n

e

 

 

 

 

 

-x cha

 

 

 

 

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

Имена переменных

Не будь переменная лишь электронной сущностью, ее можно было бы подержать в руке – своего рода программный эквивалент физического объекта. Название, которое этому соответствует, обычно должно быть существительным. Например, переменные в GUI%приложении могут называться ok_button и main_window. Даже таким переменным, которые не соответствуют объектам реального мира, можно давать имена суще% ствительные, например elapsed_time (истекшее_время) или exchan ge_rate (курс_обмена).

Не будучи «чистым» существительным, имя переменной часто оказы% вается отглагольной формой существительного, как, например, count (счетчик). Имя числовой переменной может описывать, как интерпре% тируется ее значение, например widget_length (длина_объекта). Имя булевой переменной часто является именем условного оператора, что естественно, поскольку ее значением будет «истина» или «ложь».

В объектно%ориентированных языках есть ряд соглашений по оформ% лению переменных%членов, чтобы было видно, что они – члены, а не простые локальные или (не дай бог) глобальные переменные. Это упро% щенная форма венгерской нотации, которую некоторые программи% сты находят полезной.1 Например, в C++ имена членов класса могут начинаться с символа подчеркивания, оканчиваться им или начинать% ся с m_. Первый способ считается предосудительным, поскольку связан с некоторым риском и неприятен.2 Кроме того, несколько затрудни% тельно читать переменные, имена которых начинаются или оканчива% ются символом подчеркивания.

Некоторые программисты снабжают переменные%указатели суффик% сами типа _ptr, а ссылки – суффиксами _ref. Это в некотором роде про% никновение венгерской нотации и избыточность. Тот факт, что пере% менная является указателем, неявно выражен в ее типе. Если ваша функция столь велика, что такого рода украшение кажется вам полез% ным, то, скорее всего, эта функция слишком велика!

1Разумеется, эти способы именования не оказывают влияния на открытый API класса – ведь вы сделали все переменные%члены закрытыми, не так ли?

2Глобальные идентификаторы не должны начинаться с подчеркивания, за которым идет заглавная буква. В архаичных правилах именования C много

таких странных требований.

 

 

 

 

hang

e

 

 

 

 

 

 

C

 

E

 

 

 

X

 

 

 

 

 

-

 

 

 

 

 

d

 

F

 

 

 

 

 

 

t

 

D

 

 

 

 

 

 

 

i

 

 

 

 

 

 

 

 

r

P

 

 

 

 

 

NOW!

o

 

 

 

 

 

 

 

 

 

 

 

BUY

 

 

 

 

 

to

 

 

 

 

w Click

 

 

 

80m

 

 

 

 

w

 

 

 

 

 

 

 

 

 

w

 

 

 

 

 

 

 

o

 

.

 

 

 

 

 

.c

 

 

p

 

 

 

 

g

 

 

 

 

df

 

 

n

e

 

 

 

 

-xcha

 

 

 

 

 

 

 

hang

e

 

 

 

 

 

 

 

C

 

E

 

 

 

 

X

 

 

 

 

 

 

-

 

 

 

 

 

d

 

 

F

 

 

 

 

 

 

t

 

 

D

 

 

 

 

 

 

 

i

 

 

 

 

 

 

 

 

 

r

P

 

 

 

 

 

NOW!

o

 

 

 

 

 

 

 

 

 

 

 

 

BUY

 

 

 

 

 

 

to

 

 

 

 

 

Глава 3. Что в имени тебе моем?Click

 

 

 

 

 

m

 

 

 

 

 

 

w

 

 

 

 

 

 

 

o

 

 

w

 

 

 

 

 

 

 

 

w

 

 

 

 

 

 

.c

 

 

.

 

 

 

 

 

 

 

 

p

 

 

 

 

g

 

 

 

 

 

df

 

 

n

e

 

 

 

 

 

-x cha

 

 

 

 

Существует также практика назначения переменным имен в виде акро% нимов, которые должны представлять собой краткие «осмысленные» имена. Например, можно определить переменную так: SomeTypeWithMe aningfulNaming stwmn(10); (НекоторыйТипСРазумнымИменем). Если область ви% димости невелика, такое имя может быть понятнее, чем развернутый вариант.

Лучше всего, если правила различают имена типов и имена перемен% ных. Имя типа часто начинается с заглавной буквы, а имя переменной со строчной. В результате можно увидеть такие объявления перемен% ных: Window window;.

Предпочтительней такое правило именования, которое различает имена переменных и имена типов.

Венгерская нотация

Венгерская нотация – это спорное правило, требующее включать

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

в1980%х годах в Microsoft и широко применяется в открытом Win32 API и библиотеке MFC, благодаря чему в основном и по% пулярна.

«Венгерской» она названа по имени Чарльза Симонаи, венгер% ского программиста. Другая причина такого названия в том, что имена переменных выглядят в этой нотации так, как если бы были написаны по%венгерски: непривычным к Windows про% граммистам дико видеть имена типа lpszFile, rdParam и hwndItem.

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

Имена функций

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

Разумные имена функций не должны содержать слов be, do и perform (быть, делать, выполнять). Новички часто совершают ошибку, исполь% зуя эти слова при попытке сознательно включить в имя глагол (эта функция выполняет XXX…). Это пустые звуки, не вносящие в имя ни% какого смысла.

 

 

 

 

hang

e

 

 

 

 

 

 

 

C

 

E

 

 

 

 

X

 

 

 

 

 

 

-

 

 

 

 

 

d

 

 

F

 

 

 

 

 

 

t

 

 

D

 

 

 

 

 

 

 

i

 

 

 

 

 

 

 

 

 

r

 

P

 

 

 

 

 

NOW!

o

 

 

 

 

 

 

 

 

 

 

 

 

 

BUY

 

 

 

 

 

 

to

 

 

 

 

 

w Click

 

 

 

Техническиеm

подробности

 

 

 

 

w

 

 

 

 

 

 

 

 

 

 

w

 

 

 

 

 

 

 

o

 

 

.

 

 

 

 

 

.c

 

 

 

p

 

 

 

 

g

 

 

 

 

 

df

 

 

n

e

 

 

 

 

 

-xcha

 

 

 

 

 

 

 

 

hang

e

 

 

 

 

 

 

 

C

 

E

 

 

 

 

X

 

 

 

 

 

 

-

 

 

 

 

 

d

 

 

F

 

 

 

 

 

 

t

 

 

D

 

 

 

 

 

 

 

i

 

 

 

 

 

 

 

 

 

r

P

 

 

 

 

 

NOW!

o

 

 

 

 

 

 

 

 

 

 

 

 

BUY

 

 

 

 

 

 

to

 

 

 

 

 

81Click

 

 

 

 

 

m

 

 

 

 

 

 

w

 

 

 

 

 

 

 

o

 

 

w

 

 

 

 

 

 

 

 

w

 

 

 

 

 

 

.c

 

 

.

 

 

 

 

 

 

 

 

p

 

 

 

 

g

 

 

 

 

 

df

 

 

n

e

 

 

 

 

 

-x cha

 

 

 

 

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

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

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

Употребление прописных букв

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

camelCase

camelCase активно применяется в библиотеках Java и часто в текстах C++. Название возникло благодаря сходству пропис% ных букв с горбами верблюда, а впервые этот стиль был, по% видимому, применен в языке Smalltalk в начале 1970%х.

ProperCase

Близкий родственник camelCase, отличающийся дополни% тельным выделением первой буквы. Другое название – Pascal% Case. Часто оба стиля используют совместно. Например, в Java стиль ProperCase используется для имен классов, а стиль camelCase – для членов. В методах Windows API и .NET при% меняется ProperCase.

использование_подчеркивания

Сторонников этого стиля мы находим среди авторов стандарт% ной библиотеки C++ (взгляните на состав пространства имен std) и членов GNU.

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

 

 

 

 

hang

e

 

 

 

 

 

 

C

 

E

 

 

 

X

 

 

 

 

 

-

 

 

 

 

 

d

 

F

 

 

 

 

 

 

t

 

D

 

 

 

 

 

 

 

i

 

 

 

 

 

 

 

 

r

P

 

 

 

 

 

NOW!

o

 

 

 

 

 

 

 

 

 

 

 

BUY

 

 

 

 

 

to

 

 

 

 

w Click

 

 

 

82m

 

 

 

 

w

 

 

 

 

 

 

 

 

 

w

 

 

 

 

 

 

 

o

 

.

 

 

 

 

 

.c

 

 

p

 

 

 

 

g

 

 

 

 

df

 

 

n

e

 

 

 

 

-xcha

 

 

 

 

 

 

 

hang

e

 

 

 

 

 

 

 

C

 

E

 

 

 

 

X

 

 

 

 

 

 

-

 

 

 

 

 

d

 

 

F

 

 

 

 

 

 

t

 

 

D

 

 

 

 

 

 

 

i

 

 

 

 

 

 

 

 

 

r

P

 

 

 

 

 

NOW!

o

 

 

 

 

 

 

 

 

 

 

 

 

BUY

 

 

 

 

 

 

to

 

 

 

 

 

Глава 3. Что в имени тебе моем?Click

 

 

 

 

 

m

 

 

 

 

 

 

w

 

 

 

 

 

 

 

o

 

 

w

 

 

 

 

 

 

 

 

w

 

 

 

 

 

 

.c

 

 

.

 

 

 

 

 

 

 

 

p

 

 

 

 

g

 

 

 

 

 

df

 

 

n

e

 

 

 

 

 

-x cha

 

 

 

 

так же, как данные, которые они запрашивают. Иллюстрацией слу% жит ответ (на стр. 597) на вопрос № 9 в конце этой главы.

При написании функции ee нужно подробно документировать (в соста% ве спецификации или каким%нибудь общепринятым методом в коде программы). Тем не менее имя все равно должно ясно указывать на за% дачу, которую решает функция. Что делает какая%нибудь void a()? Да что угодно!

Имена типов

То, какие типы можно создавать, зависит от языка. В языке C сущест% вуют typedef, создающие синонимы для других имен типов. С их помо% щью можно создавать более простые и удобные имена. Понятно, что ty pedef должен создавать понятное имя. Даже если это локальное опреде% ление typedef в теле функции, у него должно быть содержательное имя.

В Java, C++ и прочих OO%языках активно применяется создание но% вых типов (классов). C позволяет также определять составные типы, называемые structs. Хороший выбор имени типа имеет такое же важ% ное значение, как выбор правильных имен переменных и функций для облегчения читаемости кода. Однако строгих правил именования классов нет, поскольку классы могут служить разным целям:

Класс может описывать некий объект данных, меняющий свое со% стояние. В таком случае имя класса может быть существительным.

Это может быть объект%функция (функтор) или класс, реализую% щий виртуальный интерфейс обратного вызова. Тогда его имя может быть глаголом, возможно, включающим имя известной конструк% тивной схемы. (Gamma et al. 94)

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

Классы интерфейсов (например, абстрактные классы C++ с чисто виртуальными функциями или интерфейсы в Java и .NET) обычно называют в соответствии с возможностями интерфейса. Часто встре% чаются такие имена, как Printable и Serializable. В .NET дополни% тельно применяется венгерская нотация в виде добавления I перед именами всех интерфейсов, что приводит к появлению таких имен, как IPrintable.

Ранее мы уже говорили о том, каких имен функций нужно избегать; аналогичные правила действуют и для классов. Например, плохим именем будет DataObject – и так ясно, что класс может содержать дан% ные и будет создавать объект; нет необходимости снова это повторять.

Избегайте в именах лишних слов. В частности, в именах типов – таких слов, как class, data, object и type.