Из некоторых проектов с открытым исходным кодом я собрал следующий стиль кодирования
void someFunction(bool forget);
void ourFunction() {
someFunction(false /* forget */);
}
Я всегда сомневаюсь, что false
здесь значит. Означает ли это «забыть», или «забыть» относится к соответствующему параметру (как в случае выше), а «ложь» означает его отрицание?
Какой стиль используется чаще всего, и как лучше (или некоторые из лучших способов) избежать двусмысленности?
coding-style
comments
boolean
Йоханнес Шауб - Литб
источник
источник
someFunction(forget: true);
true
чтобыfalse
и не обновлять свой комментарий. Если вы не можете изменить API, то лучший способ это прокомментироватьsomeFunction( false /* true=forget, false=remember */)
sortAscending
и /sortDescending
или аналогичных). Теперь внутри они оба могут вызывать один и тот же закрытый метод, который может иметь такой тип параметра. На самом деле, если бы язык поддерживал это, вероятно, что я передал бы лямбда-функцию, которая содержала бы направление сортировки ...Ответы:
В приведенном вами примере кода это выглядит как
forget
аргумент флага. (Я не могу быть уверен, потому что функция является чисто гипотетической.)Аргументы флагов - это запах кода. Они указывают, что функция делает больше, чем одну вещь, а хорошая функция должна делать только одну вещь.
Чтобы избежать аргумента флага, разбейте функцию на две функции, которые объясняют разницу в имени функции.
Флаг аргумента
Нет аргумента флага
редактировать: в идеале, вам не нужно вообще обходить функцию с параметром flag. Существуют случаи, аналогичные тому, что Фаулер называет запутанной реализацией, когда полное разделение функций создает дублированный код. Однако чем выше цикломатическая сложность параметризованной функции, тем сильнее аргумент для ее избавления.
Это всего лишь догадка, но параметр с именем
forget
звучит как зависть к функциям. Почему звонящий сказал другому объекту забыть что-нибудь? Там может быть большая проблема дизайна.источник
serveTraditionalIceCream
иserveLowFatIceCream
выглядеть? У меня есть enum с 14 видами мороженого.По словам непрофессионала:
false
это буквальное.false
someFunction
не забыватьsomeFunction
что параметр забудьfalse
someFunction
помнитьНа мой взгляд, было бы лучше, если бы функция была такой:
Вы можете назвать это
или сохраните старое имя, но измените функцию-оболочку на
РЕДАКТИРОВАТЬ:
Как сказал @Vorac, всегда старайтесь использовать позитивные слова. Двойное отрицание сбивает с толку.
источник
remember
, если только имя функции не сделало значениеremember
очень очевидным.rememberToCleanUp* or *persist
или что-то.Параметр может быть хорошо назван; Трудно сказать, не зная названия функции. Я предполагаю, что комментарий был написан первоначальным автором функции, и это было напоминание о том, что переходить
false
вsomeFunction
средства, но для любого, кто придет потом, это немного неясно на первый взгляд.Использование положительного имени переменной (предлагается в Code Complete ) может быть самым простым изменением, которое облегчит чтение этого фрагмента, например
затем
ourFunction
становится:Однако использование enum делает вызов функции еще проще для понимания за счет некоторого вспомогательного кода:
Если вы
someFunction
по какой-либо причине не можете изменить сигнатуру , использование временной переменной также облегчает чтение кода, что-то вроде упрощения условных выражений, если ввести переменную не по какой-либо другой причине, кроме как для облегчения анализа кода людьми. ,источник
remember
в true означает забыть (в вашем примереsomeFunction(true /* forget */);
)?enum
сегодняшний день это лучшее решение. То, что тип может быть представлен как «тоbool
есть», они изоморфны - это не значит, что он должен быть представлен как таковой. Тот же аргумент относитсяstring
и к дажеint
.Переименуйте переменную, чтобы значение bool имело смысл.
Это в миллион раз лучше, чем добавление комментария для объяснения аргументов функции, потому что имя неоднозначное.
источник
Создайте локальное логическое значение с более описательным именем и присвойте ему значение. Таким образом, смысл будет более понятным.
Если вы не можете переименовать переменную, то комментарий должен быть немного более выразительным:
источник
/* forget */
к которой относится этот комментарий, а именно, что без объявления функции прямо перед вами может быть трудно вспомнить, что устанавливаетсяfalse
. (Вот почему я думаю, что совет @ Esailija лучше добавить перечисление, и поэтому я люблю языки, которые допускают именованные параметры.)Есть хорошая статья, в которой упоминается именно эта ситуация, так как она относится к API Qt-Style. Там она называется Ловушка булевых параметров, и ее стоит прочитать.
Суть этого заключается в:
источник
Это странный комментарий.
На
someFunction(false /* forget */);
самом деле, с точки зрения компилятораsomeFunction(false);
(комментарий удаляется). Итак, все, что делает эта строка, это вызовsomeFunction
с первым (и единственным) аргументом, установленным вfalse
./* forget */
это просто имя параметра. Это, вероятно, не более чем быстрое (и грязное) напоминание, которое на самом деле не должно быть там. Просто используйте менее двусмысленное имя параметра, и вам вообще не понадобится комментарий.источник
Один из советов чистого кода - минимизировать количество ненужных комментариев 1 (потому что они имеют тенденцию гнить) и правильно называть функции и методы.
После этого я бы просто удалил комментарий. В конце концов, современные IDE (например, eclipse) выдают окно с кодом, когда вы наводите курсор мыши на функцию. Увидев код, следует убрать неоднозначность.
1 Комментировать некоторый сложный код - это нормально.
источник
Чтобы отметить очевидное, комментарии могут лгать. Таким образом, всегда лучше , чтобы сделать ваш код самодокументируемыми , не прибегая к комментариям объяснить, потому что какой - то человек (возможно , вы) изменится
true
на ,false
а не обновлять свой комментарий.Если вы не можете изменить API, то я прибегаю к 2 вариантам
источник
Мне нравится ответ о том, чтобы сделать комментарий всегда правдивым , но, несмотря на это, я думаю, что он пропускает фундаментальную проблему с этим кодом - он вызывается с литералом.
Вы должны избегать использования литералов при вызове методов. Локальные переменные, необязательные параметры, именованные параметры, перечисления - как вы их лучше избегаете, будет зависеть от языка и того, что доступно, но старайтесь избегать их. Литералы имеют значения, но они не имеют значения.
источник
В C # я использовал именованные параметры, чтобы сделать это более понятным
Или
enum
:Или перегрузки:
Или полиморфизм`
источник
Именование должно всегда разрешать неопределенность для логических значений. Я всегда называю логическое что-то вроде «isThis» или «shouldDoThat», например:
и так далее. Но когда вы ссылаетесь на чужой код, лучше всего оставлять комментарии при передаче значений.
источник