Добавил:
Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
книги хакеры / Питер_Гудлиф_Ремесло_программиста_Практика_написания_хорошего_кода.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

 

 

 

Технические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

 

 

 

 

 

83Click

 

 

 

 

 

m

 

 

 

 

 

 

w

 

 

 

 

 

 

 

o

 

 

w

 

 

 

 

 

 

 

 

w

 

 

 

 

 

 

.c

 

 

.

 

 

 

 

 

 

 

 

p

 

 

 

 

g

 

 

 

 

 

df

 

 

n

e

 

 

 

 

 

-x cha

 

 

 

 

Класс плохих имен

Дурное имя класса может действительно сбить программистов с толку. Однажды мне довелось работать над приложением, в ко% тором был реализован конечный автомат. В силу исторических причин базовый класс каждого состояния носил название Window, хотя более разумным было бы дать ему, к примеру, имя State. Это привело в замешательство нескольких программистов, кото% рые впервые знакомились с кодом. Пуще того, базовый класс управляющего шаблона назывался Strategy, тогда как в действи% тельности он не реализовывал никакого шаблона стратегии. Ра% зобраться в существе было очень непросто. Если бы имена были выбраны лучше, было бы легче понять логику кода.

Следите за тем, чтобы описание относилось к классу данных, а не к фак# тическому объекту. Это тонкое, но важное отличие.

Пространства имен

Какое имя дать конструкции, специально созданной для сличения имен? Пространства имен C++ и C#, а также пакеты Java выполня% ют в основном функции группировки.

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

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

Выбирая имя пространства имен, старайтесь, чтобы оно имело отноше% ние к содержимому. Если оно представляет собой весь интерфейс биб% лиотеки, дайте ему такое же имя, как у библиотеки. Если содержимое является частью более крупной системы, выберите имя, которое опи% сывает эту часть; UI, filesystem или controls – все они будут хорошими

 

 

 

 

hang

e

 

 

 

 

 

 

C

 

E

 

 

 

X

 

 

 

 

 

-

 

 

 

 

 

d

 

F

 

 

 

 

 

 

t

 

D

 

 

 

 

 

 

 

i

 

 

 

 

 

 

 

 

r

P

 

 

 

 

 

NOW!

o

 

 

 

 

 

 

 

 

 

 

 

BUY

 

 

 

 

 

to

 

 

 

 

w Click

 

 

 

84m

 

 

 

 

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

 

 

 

 

именами. Не включайте в имя лишнее напоминание, что это коллек% ция объектов, например controls_group – неудачное имя.

Давайте пространствам имен и пакетам имена, логически связанные с их содержимым.

Имена макросов

Макросы – это зубодробительный инструмент в мире C/C++. Это сред% ства поиска и замены базового текста, не признающие областей види% мости. Они совершенно бестактны. Но есть такие орешки, которые без их помощи не вскрыть.

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

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

Полезно применять уникальные префиксы в виде имени проекта или файла. Например, имя PROJECTFOO_MY_MACRO значительно безопаснее, чем

MY_MACRO.

Макросы в C/C++ всегда выделяют прописными буквами, чтобы сделать хоро& шо заметными, и тщательно выбирают их имена, чтобы избежать кон& фликтов. Никогда не выделяйте прописными буквами другие объекты.

Имена файлов

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

Чтобы выбор имени файла был прост и очевиден, каждый файл дол% жен состоять из одной логической единицы. Слишком объемистые файлы чреваты возникновением проблем в будущем. Разбейте свой код на как можно большее количество файлов; тогда не только проще будет дать им имена, но уменьшится число связей и структура проекта станет понятнее.

1Кроме тех, которые обусловлены ОС или файловой системой.

 

 

 

 

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

 

 

 

 

 

85Click

 

 

 

 

 

m

 

 

 

 

 

 

w

 

 

 

 

 

 

 

o

 

 

w

 

 

 

 

 

 

 

 

w

 

 

 

 

 

 

.c

 

 

.

 

 

 

 

 

 

 

 

p

 

 

 

 

g

 

 

 

 

 

df

 

 

n

e

 

 

 

 

 

-x cha

 

 

 

 

Файл C/C++, в котором определяется интерфейс для widget, нужно на% звать widget.h, а не widget_interface.h, widget_decls.h или каким%то еще способом. Обычно каждому widget.h должен соответствовать widget.cpp или widget.c (см. «Все хорошо, что хорошо кончается» на стр. 86), где реализуется то, что декларировано в widget.h. Общее базовое имя логи% чески связывает эти файлы. Это и очевидно, и общепринято.

Существует много других тонких, но важных правил именования файлов:

Остерегайтесь употребления прописных букв. Некоторые файловые системы не способны различать регистр букв при поиске файлов по имени. А при переносе на платформу, где регистр имеет значение, ваш код может не скомпилироваться, если вы нетщательно соблю% дали единообразное применение прописных букв. Проще всего избе% жать таких неприятностей, если использовать в именах файлов ис% ключительно строчные буквы; как говорится, не можешь сделать хорошо, сделай правильно. (Разумеется, это не относится к Java, где в именах классов и интерфейсов применяется стиль PascalCase.)

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

Если в вашем проекте участвует несколько языков, не храните в од% ном и том же каталоге foo.c, foo.cpp и foo.java. Это вносит путани% цу: из какого файла должен создаваться объектный файл foo.o, а из какого – выполняемый модуль foo?

Постарайтесь дать всем создаваемым вами файлам различные име% на, даже если они разбросаны по отдельным каталогам. Так проще определить, с каким файлом вы имеете дело. Тогда станет очевид% ным, какой заголовочный файл нужен, если вы напишете #include "foo.h". При наличии двух файлов с одинаковыми именами нович% ку труднее разобраться в коде. Такие проблемы еще более осложня% ются по мере роста системы.

Один из выходов – добавить к логическому имени файла данные о пути к нему. Разместите свои файлы так, чтобы можно было вклю% чать library_one/version.h и library_two/version.h, не вызывая недо% разумений.

Выбор имен файлов существенно влияет на сложность кодирования. Однажды я работал над проектом C++, в котором большинство имен файлов точно совпадало с именами классов: класс Daffodil определял% ся в Daffodil.h (имена изменены, чтобы никого не обидеть). Однако ряд файлов именовался несколько иным способом, обычно путем сокраще% ния, например класс HerbaciousBorder определялся в HerbBdr.h. В ре% зультате искать правильное имя файла для директивы #include было сложно и долго. Мало того, реализация класса Daffodil могла не цели%