Анимация
JavaScript
|
Главная Библионтека * Решение о переводе некоторых из идентификаторов, по меньшей мере, спорное. Однако, если вы не знаете английского, то будете лишены возможности оценить юмор автора, которым он оживил большую часть своих примеров. - Ред. Если я использую функцию этим способом - как абстракцию -, то обычно объявляю ее одновременно статической, чтобы к ней нельзя было получить доступ снаружи текущего файла, и встроенной, чтобы ее вызов не приводил к накладным расходам. Не доводите процесс функционального абстрагирования до крайности. Мне доводилось видеть отличные программы, доведенные абстрагированием до полностью нечитаемого состояния такой степени, что нет ни одной функции длиннее, чем 5 или 6 строк. Получающаяся программа работает также значительно медленнее, чем необходимо, и ее исходный текст в 5 раз длиннее, чем нужно. 53.1. Код, используемый более одного раза, должен быть помещен в функцию Это правило является обратной стороной предыдущего. Если вы обнаруживаете почти идентичный код появляющимся более чем в одном месте своей программы, то этот код должен быть выделен в подпрограмму, которая вызывается из нескольких мест. Выгода состоит в меньшем размере программы и лучшей сопровождаемости вследствие упрощения программы и того, что вы должны теперь сопровождать лишь одну функцию; если вы находите ошибку, то вам нужно исправить ее только в одном месте. Как было упомянуто ранее, имя функции также дает хорошую абстракцию. Вызовы функции с хорошо выбранным именем являются обычно самодокументирующимися, устраняя необходимость в комментариях. 54. Функция должна иметь лишь одну точку выхода Это правило применимо лишь к программам на Си. Вообще, множество переходов goto к одной точке выхода лучше, чем много операторов return. Этим способом вы можете поместить точку прерывания у единственной точки выхода, вместо того, чтобы возиться с несколькими прерываниями. Например*: int возвращаемое значение = ОШИБКА; if( некое условие ) ... возвращаемое значение = НЕЧТО; goto выход; else ... возвращаемое значение = НЕЧТО ЕЩЕ; goto выход; выход: return возвращаемое значение; Этот метод не срабатывает в Си++, потому что функции конструктора вызываются неявно в качестве части объявления; объявление часто скрывает вызов функции. Если вы пропускаете объявление, то вы пропускаете и вызов конструктора. Например, в следующей программе деструктор для x вызовется, а конструктор - нет: foo() if( некое условие ) goto выход; некий класс x; Конструктор не вызывается.(Оператор goto перескакивает через него.) ... выход: Здесь вызывается деструктор для x при выходе x из области видимости. Вследствие этой проблемы лучше всего совсем избегать переходов goto в программах на Си++. 54.1. Всегда предусматривайте возврат значения из блока внешнего уровня Иногда, когда подпрограммы короткие, не стоит стараться обеспечить единственную точку выхода. (По моему мнению, правило "избегай запутанности" перекрывает любое другое правило, с которыми оно входит в конфликт). В этой ситуации всегда старайтесь убедиться, что из подпрограммы нет таких путей, которые не проходят через оператор return. Не так: if(a) ... return делай что нужно(); else ... return ОШИБКА; а так: if(a) ... return делай что нужно(); ... return ОШИБКА; В идеале, выход по ошибке организуется из внешнего уровня блока так, чтобы вы правильно обработали неожиданный аварийный выход на внешний уровень. 55. Избегайте дублирования усилий Следующий фрагмент демонстрирует эту проблему: if ( strcmp(a, b) < 0 ) else if( strcmp(a, b)>0) else if( strcmp(a, b) == 0 ) Вызов strcmp() в Си связан с немалыми накладными расходами (как в Паскале и других языках программирования), значительно лучше сделать так: int cmp = strcmp(a, b); if(cmp<0) else if(cmp>0) else остается случай cmp == 0 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 [ 20 ] 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 |