Kostenlos

Полезные конспекты книг и авторские заметки по информационным технологиям. Без формул

Text
0
Kritiken
Als gelesen kennzeichnen
Schriftart:Kleiner AaGrößer Aa

Включайте в класс как можно меньше методов.

Блокируйте неявные методы и операторы, которые вам не нужны (private).

Минимизируйте число разных методов, вызываемых классом.

Избегайте опосредованных вызовов методов других классов (цепочек вызовов).

Вообще минимизируйте сотрудничество класса с другими классами.

Инициализируйте по мере возможности все данные-члены во всех конструкторах.

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

Если сомневаетесь, выполняйте полное копирование, а не ограниченное.

Разумные причины создания класса:

– моделирование объектов реального мира;

– моделирование абстрактных объектов;

– снижение сложности;

– изоляция сложности;

– сокрытие деталей реализации;

– ограничение влияния изменений;

– сокрытие глобальных данных;

– упрощение передачи параметров в метод;

– создание центральных точек управления;

– облегчение повторного использования кода;

– планирование создания семейства программ;

– упаковка родственных операций;

– выполнение специфического вида рефакторинга.

Классы, создавать которые не следует:

– избегайте создания классов, которые все знают и все могут;

– если класс имеет только данные, но не формы поведения, то это не класс;

– если класс имеет только формы поведения, но не данные, то это не класс.

Аспекты классов, зависящие от языка:

– поведение переопределенных конструкторов и деструкторов в дереве наследования;

– поведение конструкторов и деструкторов при обработке исключений;

– важность конструкторов по умолчанию (конструкторов без аргументов);

– время вызова деструктора или метода финализации;

– целесообразность переопределения встроенных операторов языка, в том числе операторов присваивания и сравнения;

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

В настоящее время использование классов – лучший способ достижения модульности.

Метод – это отдельная функция или процедура, выполняющая одну задачу.

Имя метода говорит о его роли.

Метод должен быть документирован, форматирован.

Входные переменные метода не изменяются.

Метод не работает с глобальными переменными.

Метод имеет одну четко определенную цель, должен быть защищен от получения плохих данных, не использует магические числа; все параметры используются в методе, параметров у метода не более 7, параметры метода упорядочены.

Методы – самый эффективный способ уменьшения объема и повышения быстродействия программ.

Разумные причины создания методов:

– снижение сложности;

– формирование понятной промежуточной абстракции;

– предотвращение дублирования кода;

– переопределить небольшой грамотно организованный метод легче, чем длинный и плохо спроектированный;

– сокрытие очередности действий;

– сокрытие неудобочитаемых операций;

– изоляция непортируемого кода;

– упрощение сложных булевых проверок;

– облегчение определения неэффективных фрагментов кода.

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

Высокая связность хуже низкой.

Функциональная связность – метод выполняет одну и только одну операцию.

Последовательная связность – метод содержит операции, которые обязательно выполняются в определенном порядке, используют данные предыдущих этапов и не формируют в целом единую функцию.

Коммуникационная связность – выполняемые в методе операции используют одни и те же данные и не связаны между собой иным образом.

Временная связность – когда операции объединяются в метод на том основании, что все они выполняются в один интервал времени.

Не выполнять в методе конкретные операции непосредственно, а вызывать для их выполнения другие методы.

Неприемлемые виды связности:

Процедурная связность – когда операции в методе выполняются в определенном порядке.

Поместить разные операции в разные методы.

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

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

Стремиться создавать методы с функциональной связностью.

Советы по выбору удачных имен методов:

– описывайте все, что метод выполняет (методы с побочными эффектами избавлять от побочных эффектов);

– избегайте невыразительных и неоднозначных глаголов (роль метода должна быть очевидной);

– не используйте для дифференциации имен методов исключительно номера;

– не ограничивайте длину имен методов искусственными правилами (оптимальная длина имени переменной равняется в среднем 9—15 символам, но имена методов обычно длиннее из-за их сложности);

– для именования функции используйте описание возвращаемого значения;

– для именования процедуры используйте выразительный глагол, дополняя его объектом (кроме ООП языков);

– дисциплинированно используйте антонимы (add/remove, begin/end, create/destroy, first/last, get/put, get/set, increment/decrement, insert/delete, lock/unlock, min/max, next/previous, old/new, open/close, show/hide, source/target, start/stop, up/down);

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

Код требует минимальных изменений, если методы состоят в среднем из 100—150 строк.

Предотвращение ошибок коммуникации между методами:

– передавайте параметры в порядке «входные значения – изменяемые значения – выходные значения»;

– подумайте о создании собственных ключевых слов in и out;

– документируйте выраженные в интерфейсе предположения о параметрах.

Типы предположений:

– вид параметров: являются ли они исключительно входными, изменяемыми или исключительно выходными;

– единицы измерения (дюймы…);

– смыслы кодов статуса и ошибок, если для их представления не используются перечисления;

– диапазоны допустимых значений;

– специфические значения, которые никогда не должны передаваться в метод;

– ограничивайте число параметров метода примерно семью;

– подумайте об определении конвенции именования входных, изменяемых и выходных параметров;

– передавайте в метод те переменные или объекты, которые нужны ему для поддержания абстракции интерфейса;

– сопряжение методов должно быть минимальным;

– используйте именованные параметры;

– убедитесь, что фактические (переданные в метод) параметры соответствуют формальным (объявленные в методе);

– проверяйте все возможные пути возврата значения из функции;

– инициализируйте возвращаемое значение значением по умолчанию в начале функции;

– не возвращайте ссылки или указатели на локальные данные (вместо ссылок – данные-члены).

Макросы:

– разрабатывая макрос, заключайте в скобки все, что можно;

– заключайте макрос, включающий несколько команд, в фигурные скобки;

– не заменяйте методы макросами;

– называйте макросы, расширяющиеся в код подобно методам, так, чтобы при необходимости их можно было заменить методами;

– теоретически встраивание методов может повысить быстродействие;

– не злоупотребляйте встраиваемыми методами.

Защита от неправильных входных данных:

– проверяйте все данные из внешних источников;

– проверяйте значения всех входных параметров метода;

– решите, как обрабатывать неправильные входные данные.

Утверждение – это код, используемый во время разработки, с помощью которого программа проверяет правильность своего выполнения (логическое выражение + сообщение).

Положения по применению утверждений:

– используйте процедуры обработки ошибок для ожидаемых событий и утверждения для событий, которые происходить не должны;

– старайтесь не помещать выполняемый код в утверждения;

– используйте утверждения для документирования и проверки предусловий и постусловий;

Предусловия – это соглашения, которые клиентский код, вызывающий метод или класс, обещает выполнить до вызова метода или создания экземпляра объекта.

Постусловия – это соглашения, которые метод или класс обещает выполнить при завершении своей работы.

Для большей устойчивости кода проверяйте утверждения, а затем все равно обработайте возможные ошибки.

Способы обработки ошибок:

– вернуть нейтральное значение. В больших долгоживущих системах различные части могут разрабатываться несколькими проектировщиками 5—10 лет и более.

– заменить следующим корректным блоком данных;

– вернуть тот же результат, что и в предыдущий раз;

– подставить ближайшее допустимое значение;

– записать предупреждающее значение в файл;

– вернуть код ошибки;

– вызвать процедуру или объект-обработчик ошибок;

– показать сообщение об ошибке, где бы она ни случилась;

– обработать ошибку в месте возникновения наиболее подходящим способом;

– прекратить выполнение.

Корректность предполагает, что нельзя возвращать неточный результат; устойчивость требует всегда пытаться сделать что-то, что позволит программе продолжить работу.

Надо стараться реагировать на неправильные значения параметров одинаково во всей программе.

Предложения по исключениям:

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

– генерируйте исключения только для действительно исключительных ситуаций;

– не используйте исключения по мелочам (стараться обрабатывать ошибки локально);

– избегайте генерировать исключения в конструкторах и деструкторах, если только вы не перехватываете их позднее;

 

– генерируйте исключения на правильном уровне абстракции;

– вносите в описание исключения всю информацию о его причинах;

– избегайте пустых блоков catch;

– выясните, какие исключения генерирует используемая библиотека;

– рассмотрите вопрос о централизованном выводе информации об исключениях;

– стандартизуйте использование исключений в вашем проекте;

– рассмотрите альтернативы исключениям;

– преобразовывайте данные к нужному типу в момент ввода;

– методы с внешней стороны баррикады должны использовать обработчики ошибок, поскольку небезопасно делать любые предположения о данных; методы внутри баррикад должны использовать утверждения, так как данные, переданные им, считаются проверенными;

– промышленная версия: должна работать быстро, экономна с ресурсами, не позволяет пользователю делать опасные действия; отладочная версия: может работать медленно, может быть расточительной, может предоставлять дополнительные возможности без риска нарушить безопасность;

– внедрите поддержку отладки как можно раньше;

– исключительные случаи должны обрабатываться так, чтобы во время разработки они были очевидны, а в промышленном коде – позволяли продолжить работу;

– чем жестче требования во время разработки, тем проще эксплуатация;

– используйте встроенный препроцессор;

– используйте отладочные заглушки;

– оставьте код, который проверяет существенные ошибки;

– удалите код, проверяющий незначительные ошибки;

– удалите код, приводящий к прекращению работы программы;

– если на стадии разработки ваша программа обнаруживает ошибку, ее надо сделать незаметнее, чтобы ее могли исправить; -оставьте код, который позволяет аккуратно завершить работу программы;

– регламентируйте ошибки для отдела технической поддержки;

– убедитесь, что оставленные сообщения об ошибках дружелюбны (выводить телефон и адреса электронной почты, по которым можно о ней сообщить).

Обычно каждый метод тестируется при его создании.

Этапы конструирования классов:

1. Создание общей структуры класса.

2. Конструирование процедур класса.

3. Оценка и тестирование всего класса.

Действия по созданию метода:

1. Проектирование метода.

2. Проверка структуры.

3. Кодирование метода.

4. Пересмотр и тестирование кода.

Применение псевдокода:

– применяйте формулировки, в точности описывающие отдельные действия;

– избегайте синтаксических элементов языков программирования;

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

– пишите псевдокод на достаточно низком уровне, так, чтобы код из него генерировался практически автоматически.

Сформулируйте задачу, решаемую методом, настолько детально, чтобы можно было переходить к созданию метода.

Затруднения в выборе имени метода могут свидетельствовать о том, что его назначение не совсем понятно.

Метод должен иметь понятное, недвусмысленное имя.

В процессе написания метода думайте о том, как вы будете его тестировать.

Исследуйте функциональность, представляемую стандартными библиотеками.

Не тратьте время на реализацию готового алгоритма, по которому написана кандидатская диссертация.

Подумайте обо всем плохом, что может случиться с вашим методом.

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

Если доступные библиотеки не предоставляют нужной функциональности, имеет смысл исследовать литературу с описанием алгоритмов.

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

Этапы кодирования метода:

1. Напишите объявление метода.

2. Напишите первый и последний операторы, а псевдокод превратите в комментарии верхнего уровня.

3. Добавьте код после каждого комментария.

4. Проверьте код.

5. Исправьте неточности.

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

Проверьте, не нужна ли дальнейшая декомпозиция кода.

Умозрительно проверьте ошибки в методе.

Только около 5% всех ошибок связано с аппаратурой, компилятором или ОС.

Если вы не знаете, почему это работает, вероятно, оно и не работает на самом деле.

Не спешите и не компилируйте программу, пока не будете уверены, что она верна.

Установите наивысший уровень предупреждений компилятора.

Применяйте проверяющие средства.

Убедитесь, что каждая строка выполняется так, как вы ожидаете.

Леса – код, поддерживающий методы при тестировании и не включаемый в конечный продукт.

Полное перепроектирование нестабильного метода полностью оправданно.

Если качество метода неудовлетворительное, вернитесь к псевдокоду.

Рекурсивное применение псевдокода – разбиение метода на более мелкие при необходимости.

Комментарии должны быть адекватными и полезными.

Неявное объявление переменных – одна из самых опасных возможностей языка.

Объявляйте все переменные.

Отключите неявные объявления.

Используйте конвенции именования.

Проверяйте имена переменных.

Инициализируйте каждую переменную при ее объявлении.

Инициализируйте каждую переменную там, где она используется в первый раз (если нельзя инициализировать при объявлении).

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

Объявляйте переменные по мере возможности как const.

Не забывайте обнулять счетчики и аккумуляторы.

Специализируйте данные-члены класса в его конструкторе.

Проверяйте необходимость повторной инициализации.

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

Локализуйте обращения к переменным (уменьшать интервал).

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

Избегайте глобальных переменных из-за большого времени жизни.

Инициализируйте переменные, используемые в цикле, непосредственно перед циклом, а не в начале метода, содержащего цикл.

Не присваивайте переменной значение вплоть до его использования.

Группируйте связанные команды.

Разбивайте группы связанных команд на отдельные методы.

Начинайте с самой ограниченной области видимости и расширяйте ее только при необходимости.

Локальная область видимости способствует интеллектуальной управляемости.

Персистентность характеризует длительность существования данных.

Время связывания – момент, когда переменная и ее значение связываются вместе.

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

Последовательные данные соответствуют последовательности команд.

Селективные данные соответствуют операторам if и case.

Итеративные данные соответствуют циклам.

Используйте каждую переменную только с одной целью.

Избегайте переменных, имеющих скрытый смысл (избегайте гибридного сопряжения).

Убеждайтесь в том, что используются все объявленные переменные.

Имя переменной должно полно и точно описывать сущность, представляемую переменной.

Имена должны быть максимально конкретны.

Имя переменной описывает проблему, а не ее решение.

Отладка программы требует меньше усилий, если имена переменных состоят в среднем из 10—16 символов.

Более длинные имена лучше присваивать редко используемым или глобальным переменным, а более короткие – локальным переменным или переменным, вызываемым в циклах.

Дополняйте имена, относящиеся к глобальному пространству имен, спецификаторами.

Имена вычисляемых значений дополнять спецификатором из Total, Sum, Average, Max, Min, Record, String, Pointer в конце имени.

В именах лучше использовать антонимы: begin/end, first/last, locked/unlocked, min/max, next/previous, old/new, opened/closed, visible/invisible, source/target, source/destination, up/down.

Индексы циклов – i, j, k.

Если код часто изменяется, модернизируется, копируется, лучше делать осмысленные имена индексов.

Имя флага не должно включать фрагмент flag, потому что он ничего не говорит о сути флага.

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

Использование временных переменных говорит о том, что программист еще не полностью понял проблему.

Временным переменным давать точное описание.

Типичные имена булевых переменных: признак завершения – done, признак ошибки – error, признак обнаружения – found, признак успешного завершения – ok или success.

Присваивайте булевым переменным имена, подразумевающие значение true или false.

Используйте утвердительные имена булевых переменных.

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

Обязательно используйте конвенции именования, так как это всегда выгодно.

Советы по созданию конвенции:

Проведите различие между именами переменных и именами методов.

Проведите различие между классами и объектами.

Идентифицируйте глобальные переменные, переменные-члены, определения типов, именованные константы, элементы перечислений, неизменяемые параметры.

Формируйте имена так, чтобы их было легко читать.

Сокращение имен стало пережитком.

Не сокращайте слова только на один символ.

Всегда используйте один и тот же вариант сокращения.

Сокращайте имена так, чтобы их можно было произнести.

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

Обращайтесь к словарю для разрешения конфликтов имен.

Документируйте очень короткие имена прямо в коде при помощи таблиц.

Указывайте все сокращения в проектном документе «Стандартные аббревиатуры».

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

Избегайте обманчивых имен или аббревиатур.

Избегайте имен, имеющих похожие значения.

Избегайте переменных, имеющих разную суть, но похожие имена.

Избегайте имен, имеющих похожее звучание, таких как wrap и rap.

Избегайте имен, включающих цифры.

Избегайте орфографических ошибок.

Избегайте слов, при написании которых люди часто допускают ошибки.

Проводите различие между именами не только по регистру букв.

Избегайте смешения естественных языков.

Избегайте имен стандартных типов, переменных и методов.

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

Избегайте имен, содержащих символы, которые можно спутать с другими символами.

Избегайте «магических чисел».

Используйте в программе как константы только 0 и 1, а любые другие числа определите как литералы с понятными именами.

Пишите код, предупреждающий появление ошибки деления на 0.

Выполняйте преобразования типов понятно.

Избегайте сравнений разных типов.

Обращайте внимание на предупреждения вашего компилятора.

Проверяйте целочисленность операций деления.

Проверяйте переполнение целых чисел.

Проверяйте на переполнение промежуточные результаты.

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

Избегайте сравнений на равенство чисел с плавающей запятой.

Предупреждайте ошибки округления.

Проверяйте поддержку специальных типов данных в языке и дополнительных библиотеках.

Избегайте магических символов и строк.

Следите за ошибками завышения/занижения на единицу индексов.

Узнайте, как ваш язык и система поддерживают Unicode.

Разработайте стратегию интернационализации/локализации в ранний период жизни программы.

Если вам известно, что нужно поддерживать только один алфавит, рассмотрите вариант использования набора символов ISO8859.

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

Выберите целостную стратегию преобразования строковых типов.

Используйте логические переменные для документирования программы.

Используйте логические переменные для упрощения сложных условий.

Используйте перечислимые типы для читабельности.

Используйте перечислимые типы для надежности.

Используйте перечислимые типы для модифицируемости.

Используйте перечислимые типы как альтернативу логическим переменным.

 

Проверяйте некорректные значения в case с перечислимым типом.

Настройте первый и последний элемент перечислимого типа для использования в качестве границ циклов.

Зарезервируйте первый элемент перечислимого типа как недопустимый.

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

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

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

Используйте именованные константы в объявлениях данных.

Избегайте литеральных значений, даже «безопасных».

Если в языке их нет, имитируйте именованные константы с помощью переменных или классов правильной области видимости.

Не используйте для представления одной сущности именованные константы в одном месте и литералы в другом.

Убедитесь, что все значения индексов массива не выходят за его границы.

Обдумайте применение контейнеров вместо массивов или рассматривайте массивы как последовательные структуры (наборов, стеков, очередей и т. п.).

Проверяйте конечные точки массивов.

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

Остерегайтесь пересечения индексов – перемены мест индексов.

Принципы создания собственных типов:

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

Преимущество создания собственных типов в появлении слоя, скрывающего язык.

Избегайте предопределенных типов.

Не переопределяйте предопределенные типы.

Определите подстановки для переносимости.

Рассмотрите вопрос создания класса вместо использования typedef.

Используйте структуры для упрощения списка параметров.

Между методами должна передаваться только та информация, которую необходимо знать.

Используйте структуры для упрощения сопровождения.

Используйте технологию, не основанную на указателях.

Избегайте преднамеренных изменений глобальных данных.

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

Глобальные данные затрудняют повторное использование кода.

Глобальные данные приводят к неопределенному порядку инициализации.

Глобальные данные привносят нарушение модульности и интеллектуальной управляемости.

Глобальные данные подходят для хранения глобальных значений.

Глобальные данные подходят для эмуляции именованных констант, если они не поддерживаются.

Глобальные данные подходят для эмуляции перечислимых типов.

Глобальные данные можно использовать для оптимизации обращений к часто используемым данным.

Применение глобальных переменных позволяет избежать бродячие данные.

Начните с объявления всех переменных локальными и делайте их глобальными только по необходимости.

Различайте глобальные переменные и переменные-члены класса.

Используйте методы доступа.

Требуйте, чтобы в свойствах весь код обращался к данным через методы доступа.

Не валите все глобальные данные в одну кучу.

Управляйте доступом к глобальным переменным с помощью блокировок.

Встройте уровень абстракции в методы доступа (не используйте структуры напрямую).

Выполняйте доступ к данным на одном и том же уровне абстракции.

Разработайте соглашения по именованию, которые сделают глобальные переменные очевидными.

Создайте хорошо аннотированный список всех глобальных переменных.

Не храните промежуточных результатов в глобальных переменных.

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

Операторы:

Факт зависимости одного выражения от другого должен быть понятен из имен методов.

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

Называйте методы так, чтобы зависимости были очевидными.

Используйте параметры методов, чтобы сделать зависимости очевидными.

Документируйте неявные зависимости с помощью комментариев.

Проверяйте зависимости с помощью утверждений или кода обработки ошибок.

Располагайте взаимосвязанные действия вместе.

При написании if-выражений:

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

Убедитесь, что при сравнении на равенство ветвление корректно.

Размещайте нормальный вариант после if, а не после else.

Размещайте осмысленные выражения после оператора if.

Рассмотрите вопрос использования блока else (в 50—80% случаев использования if следовало применить и else).

Проверяйте корректность выражения else.

Проверяйте возможную перестановку блоков if и else.

Упрощайте сложные проверки с помощью вызовов логических функций.

Размещайте наиболее вероятные варианты раньше остальных.

Убедитесь, что учтены все варианты.

Замените последовательности if-then-else другими конструкциями, которые поддерживает ваш язык программирования.

В case:

– упорядочивайте варианты case по алфавиту или численно;

– поместите правильный вариант case первым;

– отсортируйте варианты по частоте.

Сделайте обработку каждого варианта case простой.

Не конструируйте искусственные переменные с целью получить возможность использовать оператор case.

Используйте вариант по умолчанию только для обработки настоящих значений по умолчанию.

Используйте вариант по умолчанию для выявления ошибок.

Старайтесь не писать код, проваливающийся сквозь блоки оператора case.

Минимизируйте число факторов, влияющих на цикл.

Вынесите за пределы цикла все управление, какое только можно.

Размещайте вход в цикл только в одном месте.

Размещайте инициализационный код непосредственно перед циклом.

Используйте while (true) для бесконечных циклов.

Предпочитайте циклы for, если они применимы.

Не используйте цикл for, если цикл while подходит больше.

Используйте {и} для обрамления выражений в цикле.

Избегайте пустых циклов.

Располагайте служебные операции либо в начале, либо в конце цикла.

Заставьте каждый цикл выполнять только одну функцию.

При завершении цикла убедитесь, что выполнение цикла закончилось.

Сделайте условие завершения цикла очевидным.

Не играйте с индексом цикла for для завершения цикла.

Избегайте писать код, зависящий от последнего значения индекса цикла.

Рассмотрите использование счетчиков безопасности, чтобы определить, не слишком ли много раз выполняется цикл.

Рассмотрите использование операторов break вместо логических флагов в цикле while.

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

Используйте continue для проверок в начале цикла.

Используйте структуру break с метками, если ваш язык ее поддерживает.

Используйте операторы break и continue очень осторожно.

Используйте порядковые или перечислимые типы для границ массивов и циклов.

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

Используйте смысловые имена во избежание пересечения индексов.

Ограничивайте видимость переменных-индексов цикла самим циклом.

Делайте циклы достаточно короткими, чтобы их можно было увидеть сразу целиком.

Ограничивайте вложенность тремя уровнями.

Выделяйте внутреннюю часть длинных циклов в отдельные методы.

Делайте длинные циклы особенно ясными.

Простое создание цикла – изнутри наружу.

Используйте return, если это повышает читабельность.

Упрощайте сложную обработку ошибок с помощью сторожевых операторов (досрочного return).

Минимизируйте число возвратов из каждого метода.

Убедитесь, что рекурсия остановится.

Предотвращайте бесконечную рекурсию с помощью счетчиков безопасности.

Ограничьте рекурсию одним методом.

Следите за стеком при использовании рекурсии.

Не используйте рекурсию для факториалов и чисел Фибоначчи.

Лучше обходиться без goto.

Код с goto переписать с помощью вложенных if.

Код с goto переписать с использованием статусной переменной.

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

Таблица с прямым доступом позволяет обращаться изначально напрямую (есть еще индексированный и ступенчатый доступ).

Используйте неявное сравнение логических величин с true или false.

Разбивайте сложные проверки на части с помощью новых логических переменных.

Размещайте сложные выражения в логических функциях.

Используйте таблицы решений для замены сложных условий.

В операторах if заменяйте негативные выражения позитивными, меняя местами блоки if и else.

Применяйте теоремы Деморгана для упрощения логических проверок с отрицаниями.

Используйте скобки для явного задания порядка вычисления.

Используйте простой метод подсчета для проверки симметричности скобок ((– +1,) – -1).

Заключайте в скобки логическое выражение целиком.

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

Неявно сравнивайте логические переменные.

Сравнивайте числа с 0.

Сравнивайте указатели с null.

В C-подобных языках помещайте константы с левой стороны сравнений.

Учитывайте разницу между a==b и a. equals (b) (Java).

Пишите обе скобки блока одновременно.

Всегда используйте скобки для условных операторов (для пояснения).

Привлекайте внимание к нужным выражениям.

Создайте для пустых выражений макрос препроцессора или встроенную функцию DoNothing ().

Подумайте, не будет ли код яснее с непустым телом цикла.

Не используйте больше 3 уровней вложенности if.