Читаемость именования логических методов

120

Простой вопрос, с точки зрения удобочитаемости, какое имя метода вы предпочитаете для логического метода:

public boolean isUserExist(...)

или:

public boolean doesUserExist(...)

или:

public boolean userExists(...)
Юваль Адам
источник
21
первый звучит какisBabbyFormed
Зависит от языка. У разных языков разные соглашения; На ум приходят Java и Objective C. Также на грани субъективного.
Джед Смит,
Субъективно - достаточно справедливо
Юваль Адам
2
Чисто субъективно. getUserExistence, userIsNotExtinctи userHasExistentialStateт.д ...
dreamlax
Сартр гордился бы
Корнел Массон

Ответы:

112
public boolean userExists(...)

Было бы моим предпочтением. Поскольку это делает ваши условные проверки более похожими на естественный английский:

if userExists ...

Но я думаю, что нет жесткого правила - просто будьте последовательны

Мартин
источник
3
"делает ваш {вызов метода} более похожим на естественный английский" звучит как отличный тест на рациональное именование по всем направлениям. прояснил мои мысли по этому поводу - спасибо!
Cori
17
С другой стороны, изолированно или не сразу после «если», тогда «userExists ()» звучит как констатация факта, а не как вопрос, как задумывалось. В отличие от IsUserExisting () или DoesUserExist (), которые следует правилам порядка слов на английском языке для простых вопросов.
Оскар Берггрен
4
..но почему методы, возвращающие bool, могут использоваться вне if? Если у них есть побочные эффекты, это еще больше запах. if IsUserExisting()и if DoesUserExist()выглядит ужасающе, и его следует избегать.
RJFalconer
@RJFalconer иногда вам может потребоваться использовать результат этого метода в нескольких местах, поэтому вы назначите его переменной. Поскольку метод вызывается userExists, какое имя переменной вы объявите? userExistsподходит для переменных, а не для методов. Как написал @Oskar - это звучит как утверждение, а не вопрос.
Ярослав
В ситуациях, когда должны быть субъект, предикат и объект, например UserSessionIsComplete или IsUserSessionComplete, какой из них вы предпочитаете?
Ян
40

Я бы сказал userExists, потому что в 90% случаев мой вызывающий код будет выглядеть так:

if userExists(...) {
  ...
}

и это очень буквально читается по-английски.

if isUserExistи if doesUserExistкажутся излишними.

Кай
источник
18

Остерегайтесь жертвовать ясностью в погоне за удобочитаемостью .

Хотя if (user.ExistsInDatabase(db))читается лучше, чем if (user.CheckExistsInDatabase(db)), рассмотрим случай класса с шаблоном построителя (или любого класса, для которого вы можете установить состояние):

user.WithName("Mike").ExistsInDatabase(db).ExistsInDatabase(db2).Build();

Неясно, ExistsInDatabaseпроверяет ли он, существует ли он, или устанавливает факт его существования. Вы не стали бы писать if (user.Age())или if (user.Name())без какого-либо значения сравнения, так почему if (user.Exists())это хорошая идея, потому что это свойство / функция имеет логический тип, и вы можете переименовать функцию / свойство, чтобы читать больше как естественный английский? Неужели так плохо следовать тому же шаблону, который мы используем для других типов, кроме логических?

С другими типами ifоператор сравнивает возвращаемое значение функции со значением в коде, поэтому код выглядит примерно так:

if (user.GetAge() >= 18) ...

Это звучит так: «если возраст пользователя больше или равен 18 ...», правда - это не «естественный английский», но я бы сказал, что object.verbникогда не напоминал естественный английский, и это просто базовый аспект современного программирования (для многие основные языки). У программистов обычно нет проблем с пониманием приведенного выше утверждения, разве следующее хуже?

if (user.CheckExists() == true)

Что обычно сокращается до

if (user.CheckExists())

Затем последовал роковой шаг

if (user.Exists())

Хотя было сказано, что «код читается в 10 раз чаще, чем пишется», также очень важно, чтобы ошибки были легко обнаружены. Предположим, у вас есть функция Exists (), которая вызывает существование объекта и возвращает истину / ложь в зависимости от успеха. Вы могли легко увидеть код if (user.Exists())и не заметить ошибку - ошибка была бы намного более очевидной, если бы код читался, if (user.SetExists())например.

Кроме того, user.Exists () может легко содержать сложный или неэффективный код, обращаясь к базе данных, чтобы что-то проверить. user.CheckExists () дает понять, что функция что-то делает.

См. Также все ответы здесь: Соглашения об именах: как назвать метод, возвращающий логическое значение?

В качестве заключительного примечания - после «Скажи, не спрашивай» многие функции, возвращающие истину / ложь, все равно исчезают, и вместо того, чтобы запрашивать у объекта его состояние, вы говорите ему сделать что-то, что он может делать в разных способы в зависимости от его состояния.

Майкл Паркер
источник
2
> Suppose you had a function called Exists() which causes the object to existЭто уже проблема. Таким методом должен быть глагол вроде Create. По крайней мере, было бы Exist, но «существовать» как глагол используется редко. It's not clear if ExistsInDatabase is checking whether it does exist, or setting the fact that it does exist.Это очень ясно. Я бы сказал, что большинство разработчиков были бы удивлены, если бы это сделало что-нибудь, кроме простого возврата логического значения.
RJFalconer
@RJFalconer Most developers- это ключ к твоему предложению. Я бы сказал, all developersбыл бы удивлен, если бы CheckExists()сделал что-нибудь, кроме проверки, что что-то существует. Дело не в том, что Exists()это ужасное имя, просто CheckExists()это имя лучше , и этот вопрос задает, как общий принцип, какой шаблон именования лучше всего? Ответ - относиться к ней как к любой другой функции, начинать имя с глагола и не использовать другой шаблон только потому, что он возвращает логическое значение.
Майкл Паркер
Да, вопрос заключается в лучшем шаблоне именования, НО для булевых методов. Методы Bool уникальны и имеют собственное общее имя - предикат. Вы не должны относиться к ним как к другим функциям. Добавление глагола рядом с вопросом в логическом имени метода является избыточным. И это отрицательно сказывается на читабельности кода. Именование булевых методов в форме вопросов без глаголов считается лучшей практикой в ​​отрасли. Примеры: docs.microsoft.com/en-us/dotnet/api/system.io.file.exists developer.android.com/reference/java/io/File#exists ()
Альмир,
@Almir File.Exists - чрезвычайно старый вызов (по крайней мере, точка net 1.1) и не является хорошим примером современных стандартов удобочитаемости. Посмотрите на современный интерфейс dot net core API, чтобы увидеть более современные примеры того, как Microsoft соглашается: github.com/dotnet/sdk , несколько случайных примеров ссылка ссылка ссылка
Майкл Паркер
15

Целью обеспечения удобочитаемости всегда должно быть написание кода, максимально приближенного к естественному языку. Так что в данном случае это userExistsкажется лучшим выбором. Тем не менее, использование префикса «is» может быть правильным, например, в других ситуациях isProcessingComplete.

Konamiman
источник
1
Для вашего второго примера ProcessingIsCompleteближе к естественным языкам? Например: if (ProcessingIsComplete ())
Ян
9

Я бы выбрал userExists (), потому что 1) это имеет смысл на естественном языке и 2) он следует соглашениям API, которые я видел.

Чтобы понять, имеет ли это смысл на естественном языке, прочтите его вслух. «Если пользователь существует» больше похоже на допустимую английскую фразу, чем «если пользователь существует» или «если пользователь существует». «Если пользователь существует» было бы лучше, но «the», вероятно, излишне в имени метода.

Чтобы узнать, существует ли файл в Java SE 6, вы должны использовать File.exists () . Похоже, что в версии 7 будет так же . C # использует то же соглашение , что и Python и Ruby . Надеюсь, это достаточно разнообразный сборник, чтобы назвать это языково-независимым ответом. В общем, я бы предпочел методы именования в соответствии с API вашего языка.

Дэвид
источник
5

Есть вещи, которые следует учитывать, которые, как мне кажется, были упущены в нескольких других ответах здесь

  1. Это зависит от того, является ли это методом класса C ++ или функцией C. Если это метод, то он, скорее всего, будет вызван if (user.exists()) { ... }или if (user.isExisting()) { ... }
    нет if (user_exists(&user)). Это причина того, что стандарты кодирования гласят, что методы bool должны начинаться с глагола, поскольку они будут читаться как предложение, когда объект находится перед ними.

  2. К сожалению, многие старые функции C возвращают 0 в случае успеха и ненулевое значение в случае неудачи, поэтому может быть сложно определить используемый стиль, если вы не следуете, чтобы все функции bool начинались с глаголов или всегда сравнивались с true, например if (true == user_exists(&user))

Ли Баллард
источник
5

Мое простое правило на этот вопрос таково:

Если в логическом методе уже ЕСТЬ глагол, не добавляйте его. В противном случае подумайте об этом. Некоторые примеры:

$user->exists()
$user->loggedIn()
$user->isGuest() // "is" added
Джонатан
источник
2

Чисто субъективно.

Я предпочитаю, userExists(...)потому что тогда такие утверждения читаются лучше:

if ( userExists( ... ) )

или

while ( userExists( ... ) )
zumalifeguard
источник
1

В данном конкретном случае первый пример - такой ужасный английский, что я вздрагиваю.

Я бы, вероятно, выбрал номер три из-за того, как он звучит при чтении операторов if. «Если пользователь существует» звучит лучше, чем «Если пользователь существует».

Конечно, предполагается, что он будет использоваться в тестах оператора if ...

Dana
источник
1

Мне нравится любой из них:

userExists(...)
isUserNameTaken(...)
User.exists(...)
User.lookup(...) != null
Джон Кугельман
источник
0

Имена методов служат для удобочитаемости, лучше всего подходят только те, которые вписываются во весь ваш код, в большинстве случаев они начинаются с условий, поэтому subjectPredicate следует естественной структуре предложения.

юань
источник
0

Почему бы тогда не переименовать собственность?

if (user.isPresent()) {
Артем Луканин
источник