Главная страница

Руководство по стилю программирования и конструированию по


Скачать 7.6 Mb.
НазваниеРуководство по стилю программирования и конструированию по
Дата18.05.2023
Размер7.6 Mb.
Формат файлаpdf
Имя файлаCode_Complete.pdf
ТипРуководство
#1139697
страница89 из 104
1   ...   85   86   87   88   89   90   91   92   ...   104
ГЛАВА 31 Форматирование и стиль
749
Else
If transactionType = Transaction_CustomerReturn Then
процесс либо оформляет автоматический возврат, либо
‘ в случае необходимости ждет подтверждения от менеджера
If transactionAmount >= MANAGER_APPROVAL_LEVEL Then
‘ пытаемся получить подтверждение от менеджера, а затем оформляем
‘ или отменяем возврат средств в зависимости
‘ от полученного подтверждения
GetMgrApproval( isTransactionApproved )
If ( isTransactionApproved ) Then
AcceptCustomerReturn( transactionAmount )
Else
RejectCustomerReturn( transactionAmount )
End If
Else
‘ подтверждение менеджера не требуется, поэтому оформляем возврат
AcceptCustomerReturn( transactionAmount )
End If
End If
End If
Next
Логическая структура кода в листинге 31-59 более прозрачна. В ходе одного ис- следования эффективности комментариев выяснилось, что их применение не всегда является абсолютным достоинством. Автор объяснил это тем, что они «на- рушают процесс визуального просмотра программы» (Shneiderman, 1980). Из этих примеров становится понятно, что
стиль комментариев очень сильно влияет на их «разрушающую» способность.
Отделяйте каждый комментарий хотя бы одной пустой строкой Наибо- лее эффективный способ беглого просмотра программы — прочитать коммента- рии, не читая при этом код. Выделение комментариев с помощью пустых строк по- могает читателю просматривать код. В листинге 31-60 приведен пример:
Листинг 31-60. Пример выделения комментария с помощью пустой строки (Java)
// комментарий 0
CodeStatementZero;
CodeStatementOne;
// комментарий 1
CodeStatementTwo;
CodeStatementThree;
Некоторые добавляют пустую строку и до, и после комментария. Две пустых строки занимают больше экранного пространства, но кто-то считает, что так код выгля- дит лучше, чем с одной строкой. Пример таких комментариев приведен в листинге
31-61:

750
ЧАСТЬ VII Мастерство программирования
Листинг 31-61. Пример выделения комментария с помощью двух пустых строк (Java)
// комментарий 0
CodeStatementZero;
CodeStatementOne;
// комментарий 1
CodeStatementTwo;
CodeStatementThree;
За исключением случаев, когда экранное пространство ограничено, это чисто эстетический вопрос, и вы можете решать его по своему усмотрению. В этой, как и во многих других ситуациях, сам факт наличия соглашения гораздо важней конкретных деталей этого соглашения.
31.7. Размещение методов
Методы состоят из отдельных операторов, данных, управ- ляющих структур, комментариев — всех тех элементов, ко- торые обсуждались в остальных частях этой главы. В дан- ном разделе рассмотрены принципы форматирования, от- носящиеся исключительно к методам.
Используйте пустые строки для разделения состав-
ных частей метода Оставьте пустые строки между за- головком метода, объявлениями данных и именованных констант (если они есть)
и телом метода.
Используйте стандартный отступ для аргументов метода Для форма- тирования заголовка метода можно задействовать те же, что и раньше, варианты форматирования: отсутствие определенного форматирования, форматирование в конце строки или стандартные размеры отступов. Как и в большинстве других случаев, стандартные отступы становятся наилучшим решением с точки зрения аккуратности, единообразия, удобства для чтения и исправления. Листинг 31-62
содержит два примера заголовков методов без определенного форматирования:
Листинг 31-62. Примеры заголовков методов,
не использующих определенного форматирования (C++)
bool ReadEmployeeData(int maxEmployees,EmployeeList *employees,
EmployeeFile *inputFile,int *employeeCount,bool *isInputError)
void InsertionSort(SortArray data,int firstElement,int lastElement)
Эти заголовки методов исключительно утилитарны. Компьютер может их прочи- тать, как, впрочем, он может прочитать и любой другой формат заголовков, од- нако у людей они вызовут затруднения. Нужно очень постараться, чтобы приду- мать еще более нечитаемый вариант.
Перекрестная ссылка О доку- ментировании методов см. под- раздел «Комментирование ме- тодов» раздела 32.5. О процессе создания метода см. раздел 9.3.
О разнице между хорошими и плохими методами см. главу 7.

ГЛАВА 31 Форматирование и стиль
751
В качестве другого подхода к форматированию заголовка метода можно предло- жить форматирование в конце строки, обычно выглядящее неплохо. В листинге
31-63 приведены те же заголовки, отформатированные по-другому:
Листинг 31-63. Примеры заголовков методов
с посредственным форматированием в конце строки (C++)
bool ReadEmployeeData( int maxEmployees,
EmployeeList *employees,
EmployeeFile *inputFile,
int *employeeCount,
bool *isInputError )
void InsertionSort( SortArray data,
int firstElement,
int lastElement )
Этот подход аккуратен и эстетически привлекателен. Его проблема в том, что он требует больших усилий при сопро- вождении, а сложные в сопровождении стили в результате вовсе не сопровождаются. Допустим, имя функции
ReadEmp-
loyeeData() изменится на ReadNewEmployeeData(). Это нарушит выравнивание первой строки относительно остальных 4-х строк. Вам придется переформати- ровать 4 строки списка параметров, выравнивая их относительно новой позиции
maxEmployees, вызванной более длинным именем функции. Вам может даже не хватить места с правой стороны экрана, поскольку элементы и так уже далеко сдвинуты вправо.
Примеры, приведенные в листинге 31-64, отформатированы с применением стан- дартных отступов. Они выглядят также эстетически привлекательно, но их сопро- вождение требует гораздо меньше усилий.
Листинг 31-64. Примеры заголовков методов,
содержащих отступы стандартного размера (C++)
public bool ReadEmployeeData(
int maxEmployees,
EmployeeList *employees,
EmployeeFile *inputFile,
int *employeeCount,
bool *isInputError
)
public void InsertionSort(
SortArray data,
int firstElement,
int lastElement
)
Перекрестная ссылка О приме- нении параметров методов см.
раздел 7.5.

752
ЧАСТЬ VII Мастерство программирования
Такой стиль лучше выдерживает модификацию. Изменение имени метода не вли- яет на остальные параметры. При добавлении/удалении параметров необходимо изменить только одну строку — плюс-минус запятую в предыдущей. Визуальные сигналы аналогичны схемам отступов, применяемым в циклах или операторах
if.
Поиск значимой информации о методах не требует просмотра разных частей стра- ницы: всегда известно, где будет находиться эта информация.
Этот стиль можно использовать в Visual Basic, хотя при этом потребуются симво- лы продолжения строки (листинг 31-65):
Листинг 31-65. Пример заголовков методов, содержащих
стандартные отступы, удобные для чтения и сопровождения (Visual Basic)
Символ «_» используется как признак переноса строки.
Public Sub ReadEmployeeData ( _
ByVal maxEmployees As Integer, _
ByRef employees As EmployeeList, _
ByRef inputFile As EmployeeFile, _
ByRef employeeCount As Integer, _
ByRef isInputError As Boolean _
)
31.8. Форматирование классов
В этом разделе рассказано об основных принципах размещения кода в классах.
В первом подразделе вы узнаете, как отформатировать интерфейс класса, во вто- ром — как оформлять реализацию класса, в последнем — мы обсудим организа- цию файлов и программ.
Форматирование интерфейсов классов
Соглашение о размещении интерфейсов классов предусмат- ривает перечисление членов класса в следующем порядке:
1. шапка с комментарием, содержащая описание класса и любые примечания, касающиеся общих вопросов его ис- пользования;
2. конструкторы и деструкторы;
3. открытые методы;
4. защищенные методы;
5. закрытые методы и члены-данные.
Форматирование реализаций классов
Реализации классов в общем случае могут размещаться в следующем порядке:
1. шапка с комментарием, описывающая содержимое файла с классом;
2. данные класса;
3. открытые методы;
4. защищенные методы;
5. закрытые методы.
Перекрестная ссылка О доку- ментировании классов см. под- раздел «Комментирование клас- сов, файлов и программ» раз- дела 32.5. О разнице между хорошими и плохими классами см. главу 6.
>

ГЛАВА 31 Форматирование и стиль
753
Если файл содержит более одного класса, четко определяйте границы
каждого класса Взаимосвязанные методы должны быть сгруппированы в классы.
Читатель, просматривающий код, должен иметь возможность легко определить,
где какой класс. Четко выделяйте каждый класс с помощью нескольких пустых строк между концом одного и началом следующего класса. Класс — как глава в книге.
В книге вы начинаете каждую главу с новой страницы и выделяете ее заголовок крупным шрифтом. Подчеркивайте начало каждого класса подобным образом.
Пример разделения классов показан в листинге 31-66:
Листинг 31-66. Пример форматирования разделения между классами на C++
Это последний метод в классе.
// Создаем строку, идентичную sourceString, за исключением пробелов,
// заменяемых подчеркиваниями.
void EditString::ConvertBlanks(
char *sourceString,
char *targetString
) {
Assert( strlen( sourceString ) <= MAX_STRING_LENGTH );
Assert( sourceString != NULL );
Assert( targetString != NULL );
int charIndex = 0;
do {
if ( sourceString[ charIndex ] == “ “ ) {
targetString[ charIndex ] = ‘_’;
}
else {
targetString[ charIndex ] = sourceString[ charIndex ];
}
charIndex++;
} while sourceString[ charIndex ] != ‘\0’;
}
Начало нового класса отмечается несколькими пустыми строками и именем этого класса.
//______________________________________________________________________
// МАТЕМАТИЧЕСКИЕ ФУНКЦИИ
//
// Этот класс содержит математические функции программы.
//______________________________________________________________________
Это первый метод в новом классе.
// Ищем арифметический максимум аргументов arg1 и arg2.
int Math::Max( int arg1, int arg2 ) {
if ( arg1 > arg2 ) {
return arg1;
}
else {
return arg2;
}
}
>
>
>

754
ЧАСТЬ VII Мастерство программирования
Этот метод отделяется от предыдущего только пустыми строками.
// Ищем арифметический минимум аргументов arg1 и arg2.
int Math::Min( int arg1, int arg2 ) {
if ( arg1 < arg2 ) {
return arg1;
}
else {
return arg2;
}
}
Избегайте излишне заметных комментариев в классах. Если вы выделяете каждый метод, комментируя его с помощью ряда звездочек, а не просто используя пустые строки, у вас будут трудности с эффективным выделением начала нового класса
(листинг 31-67):
Листинг 31-67. Пример излишнего форматирования класса (C++)
//**********************************************************************
//**********************************************************************
// МАТЕМАТИЧЕСКИЕ ФУНКЦИИ
//
// Этот класс содержит математические функции программы.
//**********************************************************************
//**********************************************************************
//**********************************************************************
// Ищем арифметический максимум аргументов arg1 и arg2.
//**********************************************************************
int Math::Max( int arg1, int arg2 ) {
//**********************************************************************
if ( arg1 > arg2 ) {
return arg1;
}
else {
return arg2;
}
}
//**********************************************************************
// Ищем арифметический минимум аргументов arg1 и arg2.
//**********************************************************************
int Math::Min( int arg1, int arg2 ) {
//**********************************************************************
if ( arg1 < arg2 ) {
return arg1;
}
else {
return arg2;
}
}
>

ГЛАВА 31 Форматирование и стиль
755
В этом примере столь многое выделено звездочками, что в результате ни на чем нельзя сделать акцент. Программа превращается в звездное небо. И хотя это больше эстетический, а не технический вопрос, но в форматировании действует прин- цип «чем меньше, тем лучше».
Если вам нужно разделять части программы длинными строками специальных символов, разработайте их иерархию (от самых плотных к самым прозрачным)
и не рассчитывайте исключительно на звездочки. Так, звездочки можно приме- нять для разделения классов, пунктирную линию — для методов, а пустые строки
— для важных комментариев. Воздерживайтесь от размещения по соседству двух строк звездочек или пунктира (листинг 31-68):
Листинг 31-68. Пример хорошего форматирования с ограничениями (C++)
//**********************************************************************
// МАТЕМАТИЧЕСКИЕ ФУНКЦИИ
//
// Этот класс содержит математические функции программы.
//**********************************************************************
Легковесность этой строки по сравнению со строкой звездочек визуально подчеркивает тот факт,
что метод подчиняется классу.
//______________________________________________________________________
// Ищем арифметический максимум аргументов arg1 и arg2.
//______________________________________________________________________
int Math::Max( int arg1, int arg2 ) {
if ( arg1 > arg2 ) {
return arg1;
}
else {
return arg2;
}
}
//______________________________________________________________________
// Ищем арифметический минимум аргументов arg1 и arg2.
//______________________________________________________________________
int Math::Min( int arg1, int arg2 ) {
if ( arg1 < arg2 ) {
return arg1;
}
else {
return arg2;
}
}
Этот совет о разграничении нескольких классов в файле относится только к слу- чаям, когда ваш язык ограничивает число файлов, используемых в программе. Если вы пишете на C++, Java, Visual Basic или других языках, поддерживающих боль- шое количество исходных файлов, помещайте в каждый файл по одному классу,
>

756
ЧАСТЬ VII Мастерство программирования если только у вас нет уважительных причин сделать иначе (например, объединить нескольких небольших классов, составляющих единый шаблон). Один класс, од- нако, может содержать группы методов, и эти группы можно выделять с помощью технологий, продемонстрированных выше.
Организация файлов и программ
Методики форматирования классов являются частным слу- чаем более общего вопроса форматирования: как органи- зовывать классы и методы внутри файла и какие классы помещать в отдельный файл в первую очередь?
Помещайте каждый класс в отдельный файл Файл —
не просто место для хранения кода. Если ваш язык позволяет, файл должен со- держать набор методов, имеющих одно общее назначение. Файл подчеркивает факт принадлежности этих методов к одному классу.
Все методы внутри файла составляют класс. Под классом понимается как фактический класс программы, так и неко- торая логическая сущность, являющаяся частью вашего про- екта.
Классы — это семантическая языковая концепция. Файлы —
это физическая концепция операционной системы. Соответствие между класса- ми и файлами случайно, и со временем оно продолжает ослабевать, поскольку все больше сред поддерживает помещение кода в базы данных или иными способа- ми скрывают взаимосвязь методов, классов и файлов.
Называйте файл в соответствии с именем класса Большинство проектов поддерживает однозначное соответствие между названиями классов и именами файлов. Так, для класса
CustomerAccount будут созданы файлы CustomerAccount.cpp
и
CustomerAccount.h.
Четко разделяйте методы внутри файла Отделяйте методы друг от друга с помощью хотя бы двух пустых строк. Пустые строки так же эффективны, как и длинные ряды звездочек или пунктира, но их гораздо проще набирать и сопро- вождать. Две или три строки нужны для визуального различия между пустыми строками внутри метода и строками, разделяющими методы (листинг 31-69:
Листинг 31-69. Пример применения пустых строк между методами (Visual Basic)
‘ ищем арифметический максимум аргументов arg1 и arg2
Function Max( arg1 As Integer, arg2 As Integer ) As Integer
If ( arg1 > arg2 ) Then
Max = arg1
Else
Max = arg2
End If
End Function
Методы разделяют минимум две пустых строки.
Перекрестная ссылка О доку- ментации см. подраздел «Ком- ментирование классов, файлов и программ» раздела 32.5.
Перекрестная ссылка О разни- це между классами и методами и о том, как сделать класс из набора методов, см. главу 6.
>

ГЛАВА 31 Форматирование и стиль
757
’ ищем арифметический минимум аргументов arg1 и arg2
Function Min( arg1 As Integer, arg2 As Integer ) As Integer
If ( arg1 < arg2 ) Then
Min = arg1
Else
Min = arg2
End If end Function
Пустые строки набирать легче любых других сепараторов, а выглядят они не хуже.
Этот пример содержит три пустых строки, и поэтому разделение между метода- ми выглядит заметней, чем пустые строки внутри каждого метода.
Упорядочивайте методы по алфавиту Альтернативой группировке взаимо- связанных функций может служить их размещение в алфавитном порядке. Если вы не можете разбить программу на классы или ваш редактор не позволяет легко находить функции, алфавитный подход может ускорить поиск.
Аккуратно упорядочивайте исходный файл на C++ Далее приведена типич- ная организация файла с исходным кодом на C++:
1. комментарий с описанием файла;
2. файлы, включаемые директивой #include;
3. определения констант, относящиеся к нескольким классам (если файл содер- жит несколько классов);
4. перечисления, относящиеся к нескольким классам (если файл содержит несколь- ко классов);
5. определения макросов;
6. определения типов, относящиеся к нескольким классам (если файл содержит несколько классов);
7. импортируемые глобальные переменные и функции;
8. экспортируемые глобальные переменные и функции;
9. переменные и функции, видимые только в этом файле;
10. классы, вместе с определениями констант, перечислений и типов, относящи- мися к конкретному классу.
Контрольный список: форматирование
Общие вопросы
 Применяется ли форматирование в основном для логи- ческого структурирования кода?
 Может ли схема форматирования применяться единообразно?
 Позволяет ли форматирование получить код, который легко сопровождать?
 Улучшает ли схема форматирования читаемость кода?
Управляющие структуры
 Содержит ли код двойные отступы в парах begin-end или {}?
 Отделяются ли последовательные блоки друг от друга пустыми строками?
 Форматируются ли сложные выражения с учетом удобочитаемости?
 Форматируются ли блоки из одного оператора единообразно?
http://cc2e.com/3194

758
ЧАСТЬ VII Мастерство программирования
 Согласуется ли стиль форматирования операторов case с форматировани- ем других управляющих структур?
 Отформатированы ли операторы goto так, что их применение очевидно?
Отдельные операторы
 Применяются ли пробелы для повышения удобочитаемости логических вы- ражений, обращений к массивам и аргументов методов?
 Выглядит ли конец строки с незавершенным оператором очевидно некор- ректным?
 Сделан ли при переносе строк отступ стандартного размера?
 Не содержит ли каждая строка более одного оператора?
 Не содержат ли операторы побочных эффектов?
 Не содержит ли каждая строка более одного определения данных?
Комментарии
 Сделаны ли в комментариях отступы такого же размера, как и в коде, кото- рый они комментируют?
 Легко ли сопровождать принятый стиль комментариев?
Методы
 Отформатированы ли аргументы всех методов так, что каждый из них лег- ко читать, исправлять и комментировать?
 Используются ли пустые строки для разделения составных частей метода?
Классы, файлы и программы
 Существует ли однозначное соответствие между классами и файлами для большинства классов и файлов?
 Если файл содержит несколько классов, сгруппированы ли методы каждо- го класса вместе, и можно ли четко выделить каждый класс?
 Разделяются ли методы в файле пустыми строками?
 Вместо более строгого организационного принципа не стоит ли упорядочить все методы по алфавиту?
Дополнительные ресурсы
Большинство учебников по программированию упоминает о форматировании и стиле вскользь, углубленное обсужде- ние стиля программирования встречается редко, а пробле- мы форматирования прорабатываются еще реже. Вопросам форматирования и стиля посвящены следующие публикации.
Kernighan, Brian W. and Rob Pike.
The Practice of Programming. Reading, MA: Addison-
Wesley, 1999. В главе 1 обсуждается стиль программирования на языках C и C++.
Vermeulen, Allan, et al.
The Elements of Java Style. Cambridge University Press, 2000.
Misfeldt, Trevor, Greg Bumgardner, and Andrew Gray.
The Elements of C++ Style. Cam- bridge University Press, 2004.
Kernighan, Brian W., and P. J. Plauger.
The Elements of Programming Style, 2d ed. New
York, NY: McGraw-Hill, 1978. Этот классический труд по стилю программирования
— первый в этом жанре.
http://cc2e.com/3101

1   ...   85   86   87   88   89   90   91   92   ...   104


написать администратору сайта