Legibilidade de nomenclatura de método booleano

120

Pergunta simples, do ponto de vista da legibilidade, qual nome de método você prefere para um método booleano:

public boolean isUserExist(...)

ou:

public boolean doesUserExist(...)

ou:

public boolean userExists(...)
Yuval Adam
fonte
21
o primeiro pareceisBabbyFormed
Depende do idioma. Idiomas diferentes têm convenções diferentes; Java e Objective C vêm à mente. Também limítrofe subjetivo.
Jed Smith,
Subjetivo - justo
Yuval Adam
2
Puramente subjetivo. getUserExistence, userIsNotExtinct, userHasExistentialStateEtc ...
dreamlax
Sartre ficaria orgulhoso
Cornel Masson

Respostas:

112
public boolean userExists(...)

Seria meu preferido. Isso torna suas verificações condicionais muito mais parecidas com o inglês natural:

if userExists ...

Mas eu acho que não existe uma regra rígida e rápida - apenas seja consistente

Martin
fonte
3
"torna sua {chamada de método} muito mais parecida com o inglês natural" soa como um ótimo teste para nomenclatura racional em toda a linha. esclareceu meu pensamento sobre o assunto - obrigado!
cori
16
Por outro lado, isoladamente ou quando não segue imediatamente "if", então "userExists ()" soa como uma declaração de fato, em vez da pergunta que pretendia. Ao contrário de "IsUserExisting ()" ou "DoesUserExist ()", que segue as regras de ordem de palavras em inglês para perguntas diretas.
Oskar Berggren de
4
..mas por que os métodos que retornam um bool seriam usados ​​fora de um if? Se eles têm efeitos colaterais, é ainda mais um cheiro. if IsUserExisting()e if DoesUserExist()parece horrível e deve ser evitado.
RJFalconer
@RJFalconer às vezes você pode precisar usar o resultado desse método em vários lugares, então você irá atribuí-lo à variável. Uma vez que o método é chamado userExists, qual nome de variável você declarará? userExistsé bom para variáveis, não métodos. Como escreveu @Oskar - parece uma declaração, não uma pergunta.
Jarosław Wlazło
Para situações em que deve haver um sujeito, predicado e um objeto, por exemplo, UserSessionIsComplete ou IsUserSessionComplete, qual você prefere?
Yang
40

Eu diria userExists, porque 90% das vezes meu código de chamada ficará assim:

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

e é lido literalmente em inglês.

if isUserExiste if doesUserExistparecem redundantes.

Kai
fonte
18

Cuidado para não sacrificar a clareza enquanto busca a legibilidade .

Embora seja if (user.ExistsInDatabase(db))mais agradável do que ler if (user.CheckExistsInDatabase(db)), considere o caso de uma classe com um padrão de construtor (ou qualquer classe na qual você possa definir o estado):

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

Não está claro se ExistsInDatabaseestá verificando se existe ou definindo o fato de que existe. Você não escreveria if (user.Age())ou if (user.Name())sem qualquer valor de comparação, então por queif (user.Exists()) uma boa ideia simplesmente porque essa propriedade / função é do tipo booleano e você pode renomear a função / propriedade para ficar mais parecido com o inglês natural? É tão ruim seguir o mesmo padrão que usamos para outros tipos que não sejam booleanos?

Com outros tipos, uma ifinstrução compara o valor de retorno de uma função a um valor no código, de forma que o código se pareça com:

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

Que se lê como "se o usuário dot get age é maior ou igual a 18 ..." true - não é "inglês natural", mas eu diria que object.verbnunca se assemelhou ao inglês natural e esta é simplesmente uma faceta básica da programação moderna (para muitas línguas convencionais). Os programadores geralmente não têm problemas para entender a declaração acima, então o que segue é pior?

if (user.CheckExists() == true)

Que normalmente é abreviado para

if (user.CheckExists())

Seguido pela etapa fatal

if (user.Exists())

Embora tenha sido dito que "o código é lido 10 vezes mais frequentemente do que escrito", também é muito importante que os erros sejam fáceis de detectar. Suponha que você tenha uma função chamada Exists () que faz com que o objeto exista e retorna verdadeiro / falso com base no sucesso. Você poderia facilmente ver o código if (user.Exists())e não localizar o bug - o bug seria muito mais óbvio se o código lesseif (user.SetExists()) por exemplo.

Além disso, user.Exists () poderia facilmente conter código complexo ou ineficiente, retornando a um banco de dados para verificar algo. user.CheckExists () deixa claro que a função faz algo.

Veja também todas as respostas aqui: Convenções de nomenclatura: como nomear um método que retorna um booleano?

Como nota final - seguindo "Diga, não pergunte", muitas das funções que retornam verdadeiro / falso desaparecem de qualquer maneira, e em vez de perguntar a um objeto por seu estado, você diz a ele para fazer algo, o que ele pode fazer de diferentes formas com base em seu estado.

Michael Parker
fonte
2
> Suppose you had a function called Exists() which causes the object to existIsso já é um problema. Esse método deve ser um verbo, como Create. No mínimo seria Exist, mas "existir" como verbo raramente é usado. It's not clear if ExistsInDatabase is checking whether it does exist, or setting the fact that it does exist.É muito claro. Eu diria que a maioria dos desenvolvedores ficaria surpresa se isso fizesse algo diferente do que apenas retornar um booleano.
RJFalconer
@RJFalconer Most developersé a chave para sua frase aqui. Eu diria que all developersficaria surpreso se CheckExists()algo diferente de verificar se algo existe. Não Exists()é um nome terrível, apenas CheckExists()é um nome melhor , e essa pergunta é, como princípio geral, qual é o melhor padrão de nomenclatura? A resposta é tratá-la como qualquer outra função, iniciar o nome com um verbo e não usar um padrão diferente apenas porque retorna um booleano.
Michael Parker
Sim, a questão é sobre o melhor padrão de nomenclatura MAS para os métodos booleanos. Os métodos Bool são únicos e têm seu próprio nome comum - predicado. Você não deve tratá-los como outras funções. Colocar um verbo ao lado da pergunta no nome do método booleano é redundante. E tem um impacto negativo na legibilidade do código. Nomear métodos booleanos na forma de perguntas, sem verbos, é aceito como a melhor prática na indústria. Exemplos: docs.microsoft.com/en-us/dotnet/api/system.io.file.exists developer.android.com/reference/java/io/File#exists ()
Almir
@Almir File.Exists é uma chamada extremamente antiga (pelo menos dot net 1.1) e não é um bom exemplo de padrões modernos de legibilidade. Veja a API dot net core moderna para exemplos mais modernos de como a Microsoft concorda: github.com/dotnet/sdk , alguns exemplos aleatórios link link link
Michael Parker
15

O objetivo da legibilidade deve ser sempre escrever código o mais próximo possível da linguagem natural. Portanto, neste caso, userExistsparece a melhor escolha. Usar o prefixo "é" pode, no entanto, ser correto em outras situações, por exemplo isProcessingComplete.

Konamiman
fonte
1
Para o seu segundo exemplo, está ProcessingIsCompletemais perto das línguas naturais? Por exemplo: if (ProcessingIsComplete ())
Yang
9

Eu escolheria userExists () porque 1) faz sentido em linguagem natural e 2) segue as convenções das APIs que vi.

Para ver se faz sentido em linguagem natural, leia em voz alta. "Se o usuário existe" soa mais como uma frase válida em inglês do que "se o usuário existe" ou "se o usuário existe". "Se o usuário existir" seria melhor, mas "o" provavelmente é supérfluo em um nome de método.

Para ver se existe um arquivo no Java SE 6, você usaria File.exists () . Parece que será o mesmo na versão 7 . C # usa a mesma convenção , assim como Python e Ruby . Felizmente, esta é uma coleção diversa o suficiente para chamá-la de uma resposta independente de linguagem. Geralmente, eu apoiaria os métodos de nomenclatura de acordo com a API do seu idioma.

David
fonte
5

Há coisas a considerar que acho que foram perdidas por várias outras respostas aqui

  1. Depende se este é um método de classe C ++ ou uma função C. Se for um método, provavelmente será chamado if (user.exists()) { ... }ou if (user.isExisting()) { ... }
    não if (user_exists(&user)). Esta é a razão por trás dos padrões de codificação que afirmam que os métodos booleanos devem começar com um verbo, pois eles serão lidos como uma frase quando o objeto estiver na frente deles.

  2. Infelizmente muitas das funções C antigas retornam 0 para sucesso e diferente de zero para falha então pode ser difícil determinar o estilo a ser usado a menos que você siga todas as funções bool com verbos ou sempre compare com verdadeiro assim if (true == user_exists(&user))

Lee Ballard
fonte
5

Minha regra simples para esta pergunta é esta:

Se o método booleano já TEM um verbo, não adicione um. Caso contrário, considere. Alguns exemplos:

$user->exists()
$user->loggedIn()
$user->isGuest() // "is" added
Jonathan
fonte
2

Puramente subjetivo.

Eu prefiro userExists(...)porque então afirmações como esta leem melhor:

if ( userExists( ... ) )

ou

while ( userExists( ... ) )
zumalifeguard
fonte
1

Neste caso particular, o primeiro exemplo é um inglês tão horrível que me faz estremecer.

Eu provavelmente escolheria o número três por causa de como soa ao lê-lo em declarações if. "Se o usuário existir" soa melhor do que "Se o usuário existir".

Isso pressupõe que será usado em testes de instrução if, é claro ...

Dana
fonte
1

Eu gosto de qualquer um destes:

userExists(...)
isUserNameTaken(...)
User.exists(...)
User.lookup(...) != null
John Kugelman
fonte
0

Os nomes dos métodos servem para facilitar a leitura, apenas aqueles que se encaixam em todo o código seriam os melhores, já que a maioria dos casos começa com condições, portanto, subjectPredicate segue a estrutura natural da frase.

Yuan
fonte
0

Por que não renomear a propriedade então?

if (user.isPresent()) {
Artem Lukanin
fonte