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

 

 

 

 

hang

e

 

 

 

 

 

 

C

 

E

 

 

 

X

 

 

 

 

 

-

 

 

 

 

 

d

 

F

 

 

 

 

 

 

t

 

D

 

 

 

 

 

 

 

i

 

 

 

 

 

 

 

 

r

P

 

 

 

 

 

NOW!

o

 

 

 

 

 

 

 

 

 

 

 

BUY

 

 

 

 

 

to

 

 

 

 

w Click

 

 

 

594m

 

 

 

 

w

 

 

 

 

 

 

 

 

 

w

 

 

 

 

 

 

 

o

 

.

 

 

 

 

 

.c

 

 

p

 

 

 

 

g

 

 

 

 

df

 

 

n

e

 

 

 

 

-xcha

 

 

 

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

Вопросы для размышления

 

 

 

 

hang

e

 

 

 

 

 

 

 

C

 

E

 

 

 

 

X

 

 

 

 

 

 

-

 

 

 

 

 

d

 

 

F

 

 

 

 

 

 

t

 

 

D

 

 

 

 

 

 

 

i

 

 

 

 

 

 

 

 

 

r

P

 

 

 

 

 

NOW!

o

 

 

 

 

 

 

 

 

 

 

 

 

BUY

 

 

 

 

 

 

to

 

 

 

 

 

Ответы и обсуждениеClick

 

 

 

 

 

m

 

 

 

 

 

 

w

 

 

 

 

 

 

 

o

 

 

w

 

 

 

 

 

 

 

 

w

 

 

 

 

 

 

.c

 

 

.

 

 

 

 

 

 

 

 

p

 

 

 

 

g

 

 

 

 

 

df

 

 

n

e

 

 

 

 

 

-x cha

 

 

 

 

1.Хорошо ли выбраны следующие имена переменных? Ответом может быть «да» (объясните почему и в каком контексте), «нет» (объясните почему) или «не знаю» (объясните почему).

a.int apple_count

b.char foo

c.bool apple_count

d.char *string

e.int loop_counter

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

foo – всегда плохое имя. Никогда не видел, чтобы кто%нибудь считал foo. loop_counter – тоже плохо; даже если цикл слишком велик для ко% роткого имени счетчика, можно выбрать более содержательное имя, которое отражало бы фактический смысл переменной, а не ее приме% нение в качестве счетчика цикла.

Трудно сказать, хорошее ли имя bool apple_count; скорее всего, нет – булева переменная не может содержать число. Возможно, оно отража% ет допустимость определенного количества яблок, но тогда следовало бы выбрать другое имя: is_apple_count_valid.

2.В каких случаях оправдан такой выбор имен функций? Какие типы возвращаемых значений или параметров предполагаются? Какие ти пы возвращаемых значений делают такие имена бессмысленными?

a.doIt(...)

b.value(...)

c.sponge(...)

d.isApple(...)

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

3.Что важнее для системы именования – легкость чтения или легкость написания кода? Как можно облегчить то или другое?

a.Сколько раз вы пишете один и тот же фрагмент кода? (Подумайте.) Сколько раз вы его читаете? Ответы на эти вопросы должны по

мочь определить относительную важность.

 

 

 

 

hang

e

 

 

 

 

 

 

 

C

 

E

 

 

 

 

X

 

 

 

 

 

 

-

 

 

 

 

 

d

 

 

F

 

 

 

 

 

 

t

 

 

D

 

 

 

 

 

 

 

i

 

 

 

 

 

 

 

 

 

r

 

P

 

 

 

 

 

NOW!

o

 

 

 

 

 

 

 

 

 

 

 

 

 

BUY

 

 

 

 

 

 

to

 

 

 

 

 

w Click

 

 

 

Главаm

3. Что в имени тебе моем?

 

 

 

 

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

 

 

 

 

 

595Click

 

 

 

 

 

m

 

 

 

 

 

 

w

 

 

 

 

 

 

 

o

 

 

w

 

 

 

 

 

 

 

 

w

 

 

 

 

 

 

.c

 

 

.

 

 

 

 

 

 

 

 

p

 

 

 

 

g

 

 

 

 

 

df

 

 

n

e

 

 

 

 

 

-x cha

 

 

 

 

b.Как вы поступаете при противоречиях в принципах именования? Допустим, вы работаете над кодом C++ в стиле camelCase и должны модифицировать библиотеку STL (используется_подчеркивание). Как лучше поступить в такой ситуации?

Яработал с базовым кодом C++, в котором такая коллизия правил именования применялась с пользой. Во внутренней логике использо% вался camelCase, а в библиотеках и компонентах, расширявших стан% дартные библиотеки, применялись правила_именования STL. Это бы% ло достаточно удобно и разграничивало отдельные части проекта.

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

4.При каком размере цикла следует дать осмысленное имя переменной цикла?

Все зависит от длины вашей веревочки. Очевидно, что цикл из 100 строк, в котором счетчик назван i, не лучший вариант.1 Вставляя в цикл дополнительный код, проверьте, не стоит ли одновременно из% менить имя счетчика цикла.

5.Если в C assert является макросом, почему его имя пишут строчными буквами? Зачем дают макросам выделяющиеся имена?

assert не выделяется заглавными буквами, потому что assert не выде% ляется заглавными буквами. В идеале следовало бы это делать, но та% ковы правила, и приходится смириться с тем, что это имя макроса вто% рого сорта. Увы.

Огонь полезен, но он может быть опасен. То же с макросами. Макросы и определения констант #defined опасны – принятие соглашения о вы% делении их имен ПРОПИСНЫМИ БУКВАМИ позволяет избежать не% хороших конфликтов с обычными именами. Это столь же разумно, как надевать защитные очки, когда рядом бродит лунатик с острой палкой.

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

Длинные расчеты легче читать, если поместить промежуточные ре% зультаты во временные переменные. Предложите хорошие правила со% ставления имен для переменных этого типа.

Плохие имена временных переменных: tmp, tmp1, tmp2 и т. д, а также a, b, c и т. д. К сожалению, они часто встречаются на практике.

Как и все прочие объекты, имена временных переменных должны быть осмысленны (например, радиус_круга в тригонометрических рас% четах или количество_яблок в программе для садоводства). На практике

1Да и сам цикл из 100 строк – не лучший вариант.

 

 

 

 

hang

e

 

 

 

 

 

 

C

 

E

 

 

 

X

 

 

 

 

 

-

 

 

 

 

 

d

 

F

 

 

 

 

 

 

t

 

D

 

 

 

 

 

 

 

i

 

 

 

 

 

 

 

 

r

P

 

 

 

 

 

NOW!

o

 

 

 

 

 

 

 

 

 

 

 

BUY

 

 

 

 

 

to

 

 

 

 

w Click

 

 

 

596m

 

 

 

 

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

 

 

 

 

 

Ответы и обсуждениеClick

 

 

 

 

 

m

 

 

 

 

 

 

w

 

 

 

 

 

 

 

o

 

 

w

 

 

 

 

 

 

 

 

w

 

 

 

 

 

 

.c

 

 

.

 

 

 

 

 

 

 

 

p

 

 

 

 

g

 

 

 

 

 

df

 

 

n

e

 

 

 

 

 

-x cha

 

 

 

 

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

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

6.Каковы достоинства и недостатки принципов именования стандарт ной библиотеки вашего языка?

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

С другой стороны, библиотеки не всегда дают лучшие образцы, поэто% му будьте осторожны! Хорошим примером служит отвратительное на% звание макроса assert в C.

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

Вполне допускается повторение имени локальной переменной в раз% личных контекстах. Иногда это оказывается хорошей практикой: за% чем каждый раз выбирать новое имя для счетчика цикла? Это только затруднило бы чтение кода.

Не закрывайте глобальные имена именами локальных переменных; это вносит путаницу и указывает на хрупкость кода.

8.Объясните сущность венгерской нотации. Каковы ее достоинства и недостатки? Согласуется ли она с современными принципами разра ботки кода?

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

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

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

 

 

 

 

hang

e

 

 

 

 

 

 

 

C

 

E

 

 

 

 

X

 

 

 

 

 

 

-

 

 

 

 

 

d

 

 

F

 

 

 

 

 

 

t

 

 

D

 

 

 

 

 

 

 

i

 

 

 

 

 

 

 

 

 

r

 

P

 

 

 

 

 

NOW!

o

 

 

 

 

 

 

 

 

 

 

 

 

 

BUY

 

 

 

 

 

 

to

 

 

 

 

 

w Click

 

 

 

Главаm

3. Что в имени тебе моем?

 

 

 

 

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

 

 

 

 

 

597Click

 

 

 

 

 

m

 

 

 

 

 

 

w

 

 

 

 

 

 

 

o

 

 

w

 

 

 

 

 

 

 

 

w

 

 

 

 

 

 

.c

 

 

.

 

 

 

 

 

 

 

 

p

 

 

 

 

g

 

 

 

 

 

df

 

 

n

e

 

 

 

 

 

-x cha

 

 

 

 

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

Таблица 1. Стандартные префиксы венгерской нотации

Префикс Значение

pуказатель на… (lp означает long pointer, старую проблему архитек% туры; если не знаете о ней – и не надо)

rссылка…

kконстанта

rg массив

bбулев (bool или C typedef)

cchar

si

short int

iint

li

long int

ddouble

ld

long double

sz

строка char, оканчивающаяся нулем (заметьте: не p)

Sstruct

Cclass (можно придумывать свои сокращения для классов)

Бойтесь венгерской нотации, как чумы.

Некоторые схемы именования имеют тайную склонность к венгерской нотации. Возьмите, например, foo_ptr и m_foo, приводившиеся в этой главе. Есть и другие изобретательные системы схожего типа: некоторые программисты называют свои глобальные переменные theFoo, а пере% менные%члены – myFoo. Наверное, это свидетельствует о том, что в вен% герской нотации заложена хорошая идея, но, доведенная до логической крайности, она становится тиранической системой. Будьте настороже.

9.Часто классы содержат члены функции, предназначенные для чте ния и записи значений определенных свойств. Какие схемы именова ния таких функций существуют и какие из них предпочтительней?

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

Есть несколько разных схем именования. Если вы пишете на C++ в стиле camelCase и у вас есть свойство foo типа Foo, можно выбрать: