
- •1. Предпосылки возникновения методологии структурного программирования. Основные принципы структурного программирования. Теорема Бёма-Якопини.
- •2. Структурное программирование. Проектирование сверху вниз. Модульное программирование. Структурное кодирование
- •4. Функции. Компактность. Правило одной операции. Опасность смешения уровней абстракции
- •5. Функции. Правило понижения. Паттерн «Абстрактная фабрика» и использование оператора switch
- •6. Аргументы функций. Приемлемое количество и качество аргументов. Побочные эффекты в функциях. Примеры
- •7. Комментарии. Основные правила написания хороших комментариев. Комментарии todo.
- •8. Комментарии. Основные признаки плохих комментариев. Примеры.
- •9. Форматирование исходного кода. Цель форматирования. Вертикальное разделение концепций, вертикальное сжатие. Вертикальное расстояние
- •10. Форматирование исходного кода. Цель форматирования. Горизонтальное форматирование. Горизонтальное разделение и сжатие. Отступы
- •11. Объекты и структуры данных. Отличия процедурного и объектно-ориентированного кода. Случаи применения
- •12. Закон Деметры. Опасность построения гибридов объектов и структур данных. Объекты передачи данных и активные записи
- •13. Обработка ошибок. Исключения и коды ошибок. Использование паттерна «Особый случай».
- •14. Использование стороннего программного кода. Учебные тесты как инструмент исследования и анализа граничного кода.
- •15. Проблемы использования стороннего программного кода. Применение паттерна «Адаптер» для организации взаимодействия с недоступным кодом.
- •16. Класс. Размеры класса. Принцип единой ответственности (srp).
- •17. Понятие связности класса. Влияние связности на размер классов.
- •18. Структурирование класса с учетом его изменений. Принципы проектирования классов в ооп.
- •19. Понятие эффективности программы. Выбор между эффективностью и удобочитаемостью. Оптимизирующие компиляторы.
- •20. Методология разработки через тестирование (tdd). Последовательность этапов разработки при использовании методологии tdd. Три закона tdd.
- •21. Тестирование как важный этап процесса разработки по. Чистота тестов. Тесты как средство обеспечения изменений. Правило «одна концепция на тест».
- •22. Экономические аспекты процесса тестирования. Тестирование методами «черного» и «белого» ящика. Невозможность исчерпывающего тестирования.
- •23. Основные принципы тестирования программного обеспечения.
- •24. Понятие отладки. Отличие между отладкой и тестированием. Средства отладки. Защитное программирование
- •25. Понятие отладки. Основные принципы отладки. Принципы локализации ошибок. Принципы устранения ошибок.
- •26. Понятие отладки. Основные подходы к отладке программ. Методы «грубой силы», индуктивная отладка, дедуктивная отладка, обратная трассировка, отладка тестированием.
- •27. Проблема ограниченности вычислительных систем. Возможности преодоления некоторых типов ограничений.
- •28. Понятие правильности программ. Доказательство правильности программ. Правильность программ
- •29. Типы разложения вычислений (сочленение, выбор, повторение).
- •If условие then оператор 1 else оператор 2
- •30. Неоднозначность определения программы. Проблема сравнения программ.
- •32. Понятие рефакторинга. Рефакторинги «Согласование различий», «Миграция данных», «Выделение метода».
- •33. Понятие рефакторинга. Рефакторинги «Встраивание метода», «Выделение интерфейса», «Перемещение метода».
- •Inline method (встраивание метода)
- •34. Понятие рефакторинга. Рефакторинги «Метод в объект», «Добавление параметра», «Параметр метода в параметр конструктора».
8. Комментарии. Основные признаки плохих комментариев. Примеры.
КОММЕНТАРИИ
Желательность комментариев, казалось бы, очевидна, однако далеко не всегда их включают в программу. Комментарии опускают с целью экономии времени. Иногда утверждают, что «комментарии будут вставлены позже». Но такая отговорка неубедительна, потому что через удивительно короткое время авторы программы обнаруживают, что забыли ее многие детали. Программы с пояснительными комментариями значительно легче отлаживать, так как они содержат дополнительную информацию для работы с программой. Просматривая чужую программу, программист часто тратит много времени, отслеживая логику программы или просто переписывая недокументированную программу, если необходимо внести в нее изменения. В этом случае все первоначально «сэкономленное» время расходуется с превышением во много раз.
ПЛОХИЕ КОММЕНТАРИИ
Большинство комментариев относится именно к этой категории. Обычно такие комментарии представляют собой «подпорки» для некачественного кода или оправдания сомнительных решений, а их текст напоминает рассуждения вслух самого программиста.
БОРМОТАНИЕ
Не стоит лепить комментарии «на скорую руку» только потому, что вам кажется, что это уместно или этого требует процесс. Если уж вы решаете написать комментарий, не жалейте времени и напишите лучший из всех возможных комментариев.
Например, следующий фрагмент я обнаружил в FitNesse. В самом деле, комментарий здесь бы пригодился. Но автор то ли торопился, то ли не придал особого значения тому, что он пишет. Его бормотание оставляет читателя в недоумении:
public void loadPropertiesO
{
try
{
String propertiesPath = propertiesLocation + "/" + PROPERTIES_FILE;
FilelnputStream propertiesStream = new FilelnputStream(propertiesPath);
loadedProperties.load(propertiesStream);
}
catchdOException e)
{
// Если нет файла свойств, загружаются настройки по умолчанию
}
}
Что означает комментарий в блоке catch? Очевидно, он что-то означал для автора, но для читателя этот смысл не доходит. Видимо, если мы получаем IOException, это означает, что файл свойств отсутствует; в этом случае должны загружаться все настройки по умолчанию. Чтобы разобраться в происходящем, нам остается только изучить код других частей системы. Любой комментарий, смысл которого приходится искать в других модулях, не несет полезной информации и не стоит битов, затраченных на его написание.
ИЗБЫТОЧНЫЕ КОММЕНТАРИИ
В листинге 4.1 приведена простая функция с совершенно лишним заголовочным комментарием. Вероятно, чтение комментария займет больше времени, чем чтение самого кода.
Листинг 4.1. waitForClose
// Вспомогательный метод; возвращает управление, когда значение this.closed истинно.
// Инициирует исключение при достижении тайм-аута.
public synchronized void waitForClose(final long timeoutMi11 is)
throws Exception
{
if(lclosed)
{
wait(timeoutMillis);
if(lclosed)
throw new ExceptionC'MockResponseSender could not be closed");
}
}
Какой цели достигает этот комментарий? Конечно, он несет не больше информации, чем программный код. Он не объясняет код, не предоставляет обоснований и не раскрывает намерений. Он читается не проще, чем сам код.
НЕДОСТОВЕРНЫЕ КОММЕНТАРИИ
Иногда с самыми лучшими намерениями программист делает в комментариях заявления, неточные и не соответствующие истине. Еще раз взгляните на совершенно лишний, но при этом слегка вводящий в заблуждение комментарий из листинга 4.1.
А вы нашли, в чем этот комментарий обманывает читателя? Метод не возвращает управление, когда значение this.closed становится истинным. Он возвращает управление, если значение this.closed истинно; в противном случае метод ожидает истечения тайм-аута, а затем инициирует исключение, если значение this.closed так и не стало истинным.
Эта крошечная дезинформация в комментарии, который читается хуже, чем сам код, может заставить другого программиста вызвать функцию в предположении, что она вернет управление сразу же, как только значение this .closed станет истинным.
ОБЯЗАТЕЛЬНЫЕ КОММЕНТАРИИ
Правила, говорящие, что каждая функция должна иметь комментарий Javadoc или что каждая переменная должна быть помечена комментарием, — обычная глупость. Такие комментарии только загромождают код, распространяют недостоверную информацию и вызывают общую путаницу и дезориентацию.
Например, требование обязательного комментария Javadoc для каждой функции приводит к появлению монстров вроде листинга 4.3. Бессмысленные комментарии не приносят никакой пользы. Они только запутывают код, повышая риск обмана и недоразумений.
Листинг 4.3.
/**
*
* @param title Название диска
* @param author Автор диска
* @param tracks Количество дорожек на диске
* @param durationlnMinutes Продолжительность воспроизведения в минутах
*/
public void addCD(String title, String author.
int tracks, int durationlnMinutes) {
CD cd = new CDO;
cd.title = title;
cd.author = author;
cd.tracks = tracks;
cd.duration = duration;
cdList.add(cd);
}
ЖУРНАЛЬНЫЕ КОММЕНТАРИИ
Некоторые программисты добавляют комментарий в начало модуля при каждом его редактировании. Такие комментарии накапливаются, образуя своего рода журнал всех вносимых изменений.
Когда-то создание и сопровождение журнальных записей в начале каждого модуля было оправдано. У нас еще не было систем управления исходным кодом, которые делали это за нас. В наши дни длинные журналы только загромождают и усложняют код. Их следует полностью удалить из ваших программ.
ШУМ
Также в программах нередко встречаются комментарии, не содержащие ничего, кроме «шума». Они лишь утверждают очевидное, не предоставляя никакой новой информации.
Эти комментарии настолько бесполезны, что мы учимся не обращать на них внимания. В процессе чтения кода наш взгляд просто скользит мимо них. Рано или поздно код вокруг таких комментариев изменяется, и они начинают лгать.
НЕ ИСПОЛЬЗУЙТЕ КОММЕНТАРИИ ТАМ, ГДЕ МОЖНО ИСПОЛЬЗОВАТЬ ФУНКЦИЮ ИЛИ ПЕРЕМЕННУЮ
Возьмем следующий фрагмент кода:
// Зависит ли модуль из глобального списка <mod> от подсистемы,
// частью которой является наш код?
if (smodulе.getDependSubsystems().contains(subSysMod.getSubSystem())) Его можно было бы перефразировать без комментария в следующем виде:
ArrayList moduleDependees = smodule.getDependSubsystemsO;
String ourSubSystem = subSysMod.getSubSystemO;
i f (moduleDependees.contai ns(ourSubSystem))
Возможно (хотя и маловероятно), автор исходного кода сначала написал комментарий, а затем — соответствующий ему код. Но после этого автор должен был переработать свой код, как это сделал я, чтобы комментарий можно было удалить.
ПОЗИЦИОННЫЕ МАРКЕРЫ
Некоторые программисты любят отмечать определенные позиции в исходных файлах. Например, недавно я обнаружил в одной из просматриваемых программ следующую строку:
// Действия //////////////////////////////////
В отдельных случаях объединение функций под такими заголовками имеет смысл. Но в общем случае они составляют балласт, от которого следует избавиться — особенно от назойливой серии косых черт в конце.
ССЫЛКИ НА АВТОРОВ
/* Добавлено Риком */
Системы контроля исходного кода отлично запоминают, кто и когда внес то или иное исправление. Нет необходимости загрязнять код подобными ссылками.
ЗАКОММЕНТИРОВАННЫЙ КОД
В программировании редко встречаются привычки более отвратительные, чем закрытие комментариями неиспользуемого кода. Никогда не делайте этого!
СЛИШКОМ МНОГО ИНФОРМАЦИИ
Не включайте в комментарии интересные исторические дискуссии или описания подробностей, не относящиеся к делу. Следующий комментарий был извлечен из модуля, который должен был проверять, что функция кодирует и декодирует данные в формате base64. Читателю кода совершенно не нужна заумная информация, содержащаяся в этом комментарии, — вполне достаточно номера RFC.
НЕОЧЕВИДНЫЕ КОММЕНТАРИИ
Связь между комментарием и кодом, который он описывает, должна быть очевидной. Если уж вы берете на себя хлопоты, связанные с написанием комментария, то по крайней мере читатель должен посмотреть на комментарий и на код и понять, о чем говорится в комментарии.