Дихотомия параметра функции
Третьего дня прислал интерн задачу на проверку, а в ней интересная проблема.
Написано хорошо, цели достигнуты, чистенько. Готов был уже слить merge request, но взгляд уперся в такой вызов (на имя функции внимание не обращаем, в реальном коде оно другое, более осмысленное):
... dumpRecord(true) ...
Спрашиваю, что это значит (интерн рядом стоял в процессе проверки)?
Это, отвечает, мол, запись структуры в поток вместе с именами полей или без них.
То есть, определение функции выглядит примерно так
fn dumpRecord(withFields: bool) {...}
Тут я сделал замечание, заставившее меня написать эту заметку.
Логический параметр делит логику функции строго на две части, поскольку значений входного параметра всего два. Очень заманчиво использовать логическую переменную там, где есть всего два состояния. Логично же, правда?
Но тут появляется проблема для читателя кода. В вызове dumpRecord(true)
без подсказки нельзя понять, что означает дихотомия в месте вызова. Хорошо, когда среда разработки подсказывает и показывает dumpRecord(withFields: true)
, но без IDE это выглядит уже не так понятно. Именованные константы, даже если их всего две (т.е. пространство все ещё разделено надвое), читаются значительно лучше: dumpRecord(withFields)
или dumpRecord(withoutFields)
.
Печатать, разумеется, больше, но читается это сильно лучше.
С точки зрения реализации это могут быть самые разные программные конструкции: список констант, перечисления, вариантный тип и т.д.
Логические константы
Оправдано использование логических констант самих по себе?
Думаю да, причем как раз там, где состояний строго два и не может быть больше, по крайней мере штатно.
... setLocked(true) setLocked(false) ... setSwitchedOn(true) setSwitchedOn(false) ...
Здесь логический параметр является продолжением написания вызова и из написания вызова же следует, что за этим вызовом всего два состояния. При этом, запись setLocked(true, true)
уже не является хорошей записью, т.к. пространство делится уже на 4 части и из написания вызова суть понять сложно.
Вывод
Интер молодец, MR поправлен и слит. Проявляйте заботу о читателе, применяйте именованные параметры.