Книга: Рефакторинг. Зачем?
Выделение функции в процессе написания
Выделение функции в процессе написания
Рекомендации прошлой главы хороши, когда вы смотрите ранее написанный или чужой код. Тогда да, чтобы разобраться в том, что написано — помогает разбить крупные функции на более мелкие.
Согласитесь, если бы код сразу был написан в виде небольших, понятных, осмысленных функций — многих проблем можно было бы избежать.
Как же писать «короткими фразами»? Разумеется, в первую очередь, это дело привычки. Не думаю, что мне будет по силам формализовать этот процесс, я лишь попробую передать свои ощущения о том, как можно себе помочь.
1. Попробуйте проговаривать то, что должен делать ваш код. При этом, первое время, может потребоваться вдумываться в свои слова более внимательно.
Например, вы говорите себе: «если точка внутри прямоугольника, то» и при этом пишите: «if (x >= Rect. Left) and (x <= Rect. Right) and (y >= Rect. Top) and (y <= Rect. Bottom) then». Кто мешает вам написать сразу «if PointOnRect(x, y, Rect) then»? И не важно, что у вас пока нет функции PointOnRect, вы её легко напишите следующим шагом. А если даже забудите — комптлятор вам подскажет.
2. Попытайьесь ещё до того, как начнёте писать код, разбить большое действие на составляющие. Банальный пример, о котором мы уже говорили — рассчёт суммы периметров. Его очень просто разбить на два действия — расчёт периметра одного поямоугольника и вычисление суммы этих величин.
3. Если объединить этот пункт с предыдущим, можно сформулировать такой приём программирования, как использование ещё не существующих функций.
begin
Rect:= ПолучитьПрямоугольник;
Point:= ПолучитьТочку;
if ТочкаВПрямоугольнике(Point, Rect) then
ДобавитьТочку(Point);
end;
В приведённом примере, функции с названиями на русском языке не существуют в момент написания фрагмента (в реальном программировании стоит использовать те названия, которые будут работать в вашей среде программирования и которые вы собираетесь оставить насовсем, это просто пример, я в своей работе стараюсь именовать функции и переменные так, чтобы это было понятно англоговорящим представителям рода человеческого).
Сам устыдился своих упрёков и решил перевести в тот код, который сам бы и написал:
begin
Rect:= GetRect;
Point:= GetPoint;
if PointOnRect(Point, Rect) then
AddPoint(Point);
end;
Так вот, несуществующие функции — это не проблема. Во–первых — каждую из них гарантированно проще написать, чем исходную функцию целиком. Во–вторых, компилятор вам подскажет, если вы забыли реализовать какую–то из них. В случае, если вы забыли какое–то действие в основном коде, вы можете это не заметить. Ну и в-третьих — вы сразу делаете код понятным, вам не приходится делать два дела вместо одного.
Пользуясь случаем, приведу ещё один довод в пользу коротких функций. Как правило, они более конкретны. То есть не «делают то, то и ещё это за одно», а делают что–то одно и только это. Так вот, если принять во внимание, что не бывает код без ошибок, а это вообще говоря так и есть, возникает проблема: как узнать правильно работает функция или нет. Разве легко это сделать, если назначение функции не совсем понятно? Чем больше у вас кода, правильную работу которого легко проверить, тем лучше.
- Введение
- Именование переменных и функций
- Стандартные имена функций и переменных
- Преобразование одной большой функции в две маленькие
- Признаки необходимости выделения функции
- Выделение функции в процессе написания
- Когда не следует выделять функцию
- Использование модулей
- Более сложные способы организации данных
- Объединение данных и кода
- Приватные члены класса
- Свойства
- Наследование
- Содержание книги
- Популярные страницы
- Аргументы функции в Python
- 3. Функции
- Новые функции API для работы с Blob и массивами
- Стиль написания исходного кода
- Продажи в процессе
- 3.2.1.2. Начальное выделение памяти: malloc()
- Математические функции
- Размытые функции
- 7.3. Финансовые функции
- 4.3. Логические функции и таблицы истинности
- B1.7. Функции обработки ошибок
- 9.1.4.2. Функции-оболочки: execl() и др.