Исследование длинных списков параметров
День 14 конкурса качества кода Бена Оренштейна
Начну с небольшого признания: в моей кодовой базе есть метод, который принимает 11 аргументов.
Согласно правилам для разработчиков Санти Метца, в метод следует передавать не более четырех параметров. Если вы передаете хэш, то каждый параметр в этом хеше считается аргументом. Для этого есть несколько веских причин:
- Если вы передаете методу 11 аргументов, вы почти наверняка нарушаете принцип единой ответственности. Как часто методу, у которого есть только одна обязанность, требуется 11 различных битов информации для выполнения этой обязанности?
- О длинных списках параметров трудно рассуждать. По мнению умных людей, мы можем одновременно удерживать в рабочей памяти только семь вещей. Выйдите намного дальше этого, и вы начнете бороться. У вас закончилась оперативная память, и теперь вы нажимаете файл подкачки.
Если вы ищете свой код с помощью регулярного выражения /\(.*,.*,.*,.*\)/
, вы можете найти любой метод, который принимает четыре или более аргументов. Для Rubyists многие люди на челлендж-форуме рекомендовали гем reek, который просматривает ваш код и выявляет запахи кода. Если у вас есть метод, который принимает большое количество аргументов, рассмотрите следующие способы его уменьшения:
Параметры, которые должны быть переменными экземпляра
Если многие методы вашего класса принимают один и тот же параметр, подумайте, принадлежит ли этот параметр атрибуту самого экземпляра.
Сгустки данных
У вас есть наборы параметров, которые часто передаются вместе? Может иметь смысл извлечь их в содержащий объект. Классический пример — передача координат x и y методу.
def foobar(x, y) # ... end foobar(1, 2)
Каждый раз, когда вы используете этот метод, вам придется указывать аргументы x и y в правильном порядке. Это можно упростить, если метод принимает наш новый класс Point
в качестве единственного параметра.
def foobar(point) # ... end foobar Point.new(1, 2)
Это имеет несколько преимуществ. Мы можем расширить поведение класса Point
, не меняя сигнатуру метода foobar
. Мы можем изменить сигнатуру метода foobar
, не путая, какая часть списка аргументов соответствует нашим координатам. Все выигрывают.
Муфта управления
Если метод принимает флаг, который радикально меняет его поведение, вероятно, должно быть два метода. Подробнее об этом читайте в статье Этот превосходный мыслебот.
Дальнейшее чтение
Этот пост является частью моей серии, следующей за 30 Day Code Quality Challenge Бена Оренштейна. Любая полезная информация, найденная в этих сообщениях, полностью благодаря ему и другим замечательным людям на форуме задач.