Skip to content

Latest commit

 

History

History
88 lines (63 loc) · 13.9 KB

chapter_7.md

File metadata and controls

88 lines (63 loc) · 13.9 KB

Глава 7. Высококачественные методы

...методы — величайшее изобратение в области компьютерных наук. Методы облегчают чтение и понимание программ в большей степени, чем любая другая возможность языка программирования (с. 159)

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

  • Самая важная причина — снижение сложности (без абстрагирующей силы методов сложные программы было бы невозможно охватить умом)
  • Самая популярная причина — желание избежать дублирования кода
  • Удачно названный метод формирует понятную промежуточную абстракцию, что облегчает чтение и понимание кода
  • Небольшой и понятный метод можно легко переопределить, что поможет при работе с наследованием
  • Сокрытие порядка выполнения действий
  • Сокрытие операций на указателями
  • Улучшение портируемости за счёт изолирования непортируемого кода в отдельных методах
  • Упрощение сложных логический проверок за счёт сокрытия деталей проверки в методе с простым, описательным именем
  • Методы позволяют выполнять оптимизацию кода в одном месте, повышая быстродействие всех фрагментов, которые его используют

Но методы используют и для простых операций. На практике технически простая операция может быть сложной для понимания, а метод с понятным именем решает эту проблему (например, метод convert_pixels_to_points() при чтении кода будет понятнее, чем его содержимое, даже если это всего одна строка кода). К тому же простые операции имеют свойство усложняться со временем.

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

На уровне методов важнейшим принципом проектирования является стремление к функциональной связности (cohesion).

...цель в том, чтобы каждый метод эффективно решал одну задачу и больше ничего не делал (с. 164)

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

Вид Описание Оценка Лечение
Функциональная Метод выполняет одну и только одну операцию 😆
Последовательная Метод содержит операции, которые выполняются в определённой порядке, и используют данные предыдущих этапов 😃 Разделить на несколько методов
Коммуникационная Метод содержит операции, которые используют одни и те же данные, но больше никак друг с другом не связаны 😃 Разделить на несколько методов
Временная Операции объединены в метод, потому что выполняются в один интервал времени 😃 Заменить операции на вызов отдельных методов
Процедурная Операции объединены в метод, потому что выполняются друг за другом, но не связаны одной задачей или же решают её не полностью 😞 Вынести операции в отдельные методы; на их основе создать метод, который будет решать задачу целиком
Логическая Метод содержит несколько операций, а выбор выполняемой операции происходит на основе условной логики 😞 Разделить на несколько методов
Случайная Выполняемыми в методе операциями никак не связаны 😡 Спроектировать и реализовать новые методы с нуля

Удачные имена методов

Имя метода должно ясно описывать всё, что он делает (с. 167)

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

Совет Пример
Наименование метода = выразительный глагол + возвращаемый объект order.calculateDeliveryTime()
Опишите в имени метода все выходные данные и все побочные эффекты, а лучше вообще избегайте побочных эффектов order.createAndNotifyCustomer() лучше, чем order.process()
Избегайте невыразительных глаголов order.sendNotificationEmail() лучше, чем order.performNotification()
Если метод что-то возвращает (т.е. является функцией), учитывайте тип возвращаемого значения order.getCustomer() лучше, чем order.customerProfileData()
Дисциплинированно используйте антонимы для наименования методов с противоположной функциональностью
Договоритесь о конвенции именования часто используемых операций Единообразие лучше, чем order.getCustomer, cart.customer(), payment.customer.get() и так далее
Не ограничивайте длину методов искуственно; лучше длинное, но точное наименование, чем короткое и бессмысленное

Насколько объёмным может быть метод?

В теоретических работах длину метода часто советуют ограничивать числом строк, помещающихся на экране монитора (с. 169)

  • Многие методы в объектно-ориентированных программах будут короткими методами доступа
  • Обычные методы могут занимать до 100-200 строк
  • К методам, занимающим более 200 строк следует относиться с осторожностью

Советы по использованию параметров

Интерфейсы между методами — один из основных источников ошибок (с. 170)

Вот несколько советов по их предотвращению.

  • Всегда используйте все параметры класса
  • Не используйте параметры как переменные внутри метода
  • Передавайте переменные статуса или коды ошибки последними, потому что они являются второстепенными по отношению к главной цели метода
  • Если вы предполагаете, что передаваемые в метод данные должны иметь определённые характеристики, сразу же документируйте эти предположения (пишите комментарии, не дожидаясь завершения работы)
  • Ограничивайте число параметров метода примерно семью (см. магическое число семь плюс-минус два)
  • Передавайте в метод те объекты или переменные, которые нужны для поддержания абстракции интерфейса
    • Если абстракция метода подразумевает, что он ожидает несколько элементов данных, которые чисто случайно принадлежат одному объекту, передавайте эти элементы по отдельности
    • Если абстракция метода подразумевает, что он работает с частью данных определённого объекта (т.е. объект важен для асбтракции формируемой методом), передавайте объект целиком, а не его отдельные элементы
  • Используйте именованные параметры, чтобы не перепутать порядок агрументов при вызове метода
  • Убедитесь, что тип фактических параметров соответсвует типу, указанному в значениях по умолчанию (строго типизированные языки защищают от этой ошибки на уровне предупреждений компилятора)

Функции и процедуры

Методы могут быть представлены функциями и процедурами. Функции возвращают значение, а процедуры — нет (но во многих языках они синтаксически возвращают void).

Возврат значений из функции

При использовании функций есть риск того, что она не вернёт нужное значение. Чтобы избежать этого, следует:

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