Czytelność nazewnictwa metod logicznych

120

Proste pytanie, z punktu widzenia czytelności, jaką nazwę preferujesz dla metody logicznej:

public boolean isUserExist(...)

lub:

public boolean doesUserExist(...)

lub:

public boolean userExists(...)
Yuval Adam
źródło
21
pierwszy brzmi jakisBabbyFormed
Zależy od języka. Różne języki mają różne konwencje; Przychodzą mi na myśl Java i Objective C. Również subiektywna granica.
Jed Smith
Subiektywny - dość sprawiedliwy
Yuval Adam
2
Czysto subiektywne. getUserExistence, userIsNotExtinct, userHasExistentialStateEtc ...
dreamlax
Sartre byłby dumny
Cornel Masson

Odpowiedzi:

112
public boolean userExists(...)

Wolałbym. Ponieważ sprawia, że ​​testy warunkowe bardziej przypominają naturalny angielski:

if userExists ...

Ale myślę, że nie ma sztywnej i szybkiej zasady - po prostu bądź konsekwentny

Jaskółka oknówka
źródło
3
"sprawia, że ​​twoje {wywołanie metody} bardziej przypomina naturalny angielski" brzmi jak świetny test na racjonalne nazewnictwo we wszystkich obszarach. wyjaśniłem moje myślenie w tej sprawie - dzięki!
cori
16
Z drugiej strony, oddzielnie lub gdy nie następuje bezpośrednio po wyrażeniu „if”, wówczas „userExists ()” brzmi raczej jak stwierdzenie faktu, a nie pytanie, na jakie było przeznaczone. W przeciwieństwie do „IsUserExisting ()” lub „DoesUserExist ()”, które są zgodne z regułami kolejności słów w języku naturalnym w języku angielskim dla prostych pytań.
Oskar Berggren
4
..ale dlaczego metody zwracające wartość bool miałyby być używane poza if? Jeśli mają skutki uboczne, to jeszcze bardziej przypomina zapach. if IsUserExisting()i if DoesUserExist()wygląda przerażająco i należy ich unikać.
RJFalconer,
@RJFalconer czasami może zajść potrzeba użycia wyniku tej metody w kilku miejscach, więc przypiszesz go do zmiennej. Skoro wywoływana jest metoda userExists, jaką nazwę zmiennej zadeklarujesz? userExistsjest dobre dla zmiennych, a nie metod. Jak napisał @Oskar - to brzmi jak stwierdzenie, a nie pytanie.
Jarosław Wlazło
W sytuacjach, w których musi istnieć podmiot, predykat i obiekt, na przykład UserSessionIsComplete lub IsUserSessionComplete, który preferujesz?
Yang
40

Powiedziałbym userExists, ponieważ w 90% przypadków mój kod wywoławczy będzie wyglądał tak:

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

i brzmi bardzo dosłownie po angielsku.

if isUserExisti if doesUserExistwydają się zbędne.

Kai
źródło
18

Uważaj, aby nie tracić przejrzystości , dążąc do czytelności .

Chociaż if (user.ExistsInDatabase(db))czyta ładniej niż if (user.CheckExistsInDatabase(db)), rozważ przypadek klasy ze wzorcem budującym (lub dowolną klasą, na którą możesz ustawić stan):

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

Nie jest jasne, czy ExistsInDatabasechodzi o sprawdzenie, czy istnieje, czy o ustalenie faktu, że istnieje. Nie zapisałbyś if (user.Age())ani if (user.Name())bez wartości porównawczej, więc dlaczego jest if (user.Exists())to dobry pomysł tylko dlatego, że ta właściwość / funkcja jest typu boolowskiego i możesz zmienić nazwę funkcji / właściwości, aby bardziej przypominała naturalny angielski? Czy to źle podążać za tym samym wzorcem, którego używamy dla innych typów niż logiczne?

W przypadku innych typów ifinstrukcja porównuje zwracaną wartość funkcji z wartością w kodzie, więc kod wygląda mniej więcej tak:

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

Czyli „jeśli użytkownik dot get wiek jest większy lub równy 18 ...” prawda - to nie jest „naturalny angielski”, ale twierdziłbym, że object.verbnigdy nie przypominał naturalnego angielskiego i jest to po prostu podstawowy aspekt współczesnego programowania (np. wielu popularnych języków). Programiści generalnie nie mają problemu ze zrozumieniem powyższego stwierdzenia, więc czy następujące jest gorsze?

if (user.CheckExists() == true)

Który jest zwykle skracany do

if (user.CheckExists())

Następuje fatalny krok

if (user.Exists())

Chociaż powiedziano, że „kod jest czytany 10 razy częściej niż pisany”, bardzo ważne jest również, aby błędy były łatwe do wykrycia. Załóżmy, że masz funkcję o nazwie Exists (), która powoduje, że obiekt istnieje i zwraca wartość true / false na podstawie sukcesu. Możesz łatwo zobaczyć kod if (user.Exists())i nie zauważyć błędu - błąd byłby znacznie bardziej oczywisty, gdyby kod był czytany if (user.SetExists())na przykład.

Dodatkowo user.Exists () może z łatwością zawierać złożony lub nieefektywny kod, przechodząc do bazy danych w celu sprawdzenia czegoś. user.CheckExists () wyjaśnia, że ​​funkcja coś robi.

Zobacz także wszystkie odpowiedzi tutaj: Konwencje nazewnictwa: Jak nazwać metodę, która zwraca wartość logiczną?

Na koniec - po „Tell Don't Ask” wiele funkcji, które zwracają prawda / fałsz, i tak znika, a zamiast pytać obiekt o jego stan, każesz mu zrobić coś, co może zrobić w inny sposób sposoby oparte na jego stanie.

Michael Parker
źródło
2
> Suppose you had a function called Exists() which causes the object to existTo już jest problem. Taka metoda powinna być czasownikiem, na przykład Create. Przynajmniej tak by było Exist, ale „istnieć” jako czasownik jest rzadko używany. It's not clear if ExistsInDatabase is checking whether it does exist, or setting the fact that it does exist.To jest bardzo jasne. Twierdzę, że większość programistów byłaby zaskoczona, gdyby spowodowało to coś innego niż tylko zwrócenie wartości logicznej.
RJFalconer,
@RJFalconer Most developersjest kluczem do twojego zdania. Powiedziałbym, że all developersbyłbym zaskoczony, gdyby CheckExists()zrobił coś innego niż sprawdzenie, czy coś istnieje. To nie Exists()jest okropne imię, po prostu CheckExists()jest to lepsze imię, a to pytanie brzmi, jako ogólna zasada, jaki jest najlepszy wzorzec nazewnictwa? Odpowiedź brzmi: potraktuj ją jak każdą inną funkcję, rozpocznij nazwę od czasownika i nie używaj innego wzorca tylko dlatego, że zwraca wartość logiczną.
Michael Parker
Tak, pytanie dotyczy najlepszego wzorca nazewnictwa, ALE dla metod boolowskich. Metody logiczne są unikalne i mają swoją wspólną nazwę - predykat. Nie powinieneś traktować ich jak innych funkcji. Umieszczanie czasownika obok pytania w nazwie metody logicznej jest zbędne. Ma też negatywny wpływ na czytelność kodu. Nazywanie metod boolowskich w formie pytań bez czasowników jest uznawane za najlepszą praktykę w branży. Przykłady: docs.microsoft.com/en-us/dotnet/api/system.io.file.exists developer.android.com/reference/java/io/File#exists ()
Almir,
@Almir File.Exists jest bardzo starym wywołaniem (przynajmniej dot net 1.1) i nie jest dobrym przykładem nowoczesnych standardów czytelności. Przyjrzyj się nowoczesnemu interfejsowi API dot net core, aby zobaczyć bardziej nowoczesne przykłady tego, jak Microsoft się zgadza: github.com/dotnet/sdk , kilka losowych przykładów link link link
Michael Parker
15

Celem czytelności zawsze powinno być pisanie kodu jak najbardziej zbliżonego do języka naturalnego. Więc w tym przypadku userExistswydaje się najlepszym wyborem. Jednak użycie przedrostka „jest” może być poprawne, na przykład w innych sytuacjach isProcessingComplete.

Konamiman
źródło
1
Jeśli chodzi o twój drugi przykład, jest ProcessingIsCompletebliżej języków naturalnych? Na przykład: if (ProcessingIsComplete ())
Yang
9

Wybrałbym userExists (), ponieważ 1) ma to sens w języku naturalnym i 2) jest zgodne z konwencjami API, które widziałem.

Aby sprawdzić, czy ma to sens w języku naturalnym, przeczytaj to na głos. „Jeśli użytkownik istnieje” brzmi bardziej jak poprawne angielskie wyrażenie niż „jeśli użytkownik istnieje” lub „jeśli istnieje użytkownik”. „Jeśli użytkownik istnieje” byłoby lepsze, ale „the” jest prawdopodobnie zbędne w nazwie metody.

Aby sprawdzić, czy plik istnieje w Java SE 6, należy użyć funkcji File.exists () . Wygląda na to, że będzie tak samo w wersji 7 . C # używa tej samej konwencji , co Python i Ruby . Miejmy nadzieję, że jest to zbiór wystarczająco zróżnicowany, aby nazwać to odpowiedzią niezależną od języka. Ogólnie rzecz biorąc, byłbym po stronie metod nazewnictwa zgodnych z API twojego języka.

David
źródło
5

Są rzeczy do rozważenia, o których myślę, że pominęło kilka innych odpowiedzi

  1. Zależy to od tego, czy jest to metoda klasy C ++, czy funkcja C. Jeśli jest to metoda, prawdopodobnie zostanie wywołana if (user.exists()) { ... }lub if (user.isExisting()) { ... }
    nie if (user_exists(&user)). To jest powód, dla którego standardy kodowania określają, że metody bool powinny zaczynać się od czasownika, ponieważ będą one czytane jak zdanie, gdy obiekt będzie przed nimi.

  2. Niestety wiele starych funkcji C zwraca 0 dla sukcesu i niezerowe dla niepowodzenia, więc może być trudne określenie używanego stylu, chyba że śledzisz wszystkie funkcje bool zaczynające się od czasowników lub zawsze porównując z prawdą w ten sposób if (true == user_exists(&user))

Lee Ballard
źródło
5

Moja prosta zasada na to pytanie jest taka:

Jeśli metoda boolowska ma już czasownik, nie dodawaj go. W przeciwnym razie rozważ to. Kilka przykładów:

$user->exists()
$user->loggedIn()
$user->isGuest() // "is" added
Jonathan
źródło
2

Czysto subiektywne.

Wolę, userExists(...)bo wtedy takie stwierdzenia czytaj lepiej:

if ( userExists( ... ) )

lub

while ( userExists( ... ) )
zumalifeguard
źródło
1

W tym konkretnym przypadku pierwszym przykładem jest tak okropny angielski, że aż się krzywię.

Prawdopodobnie wybrałbym numer trzy ze względu na to, jak to brzmi podczas czytania stwierdzeń if. „Jeśli użytkownik istnieje” brzmi lepiej niż „Jeśli użytkownik istnieje”.

Zakłada się, że będzie on używany w testach instrukcji jeśli oczywiście ...

Dana
źródło
1

Podoba mi się każdy z tych:

userExists(...)
isUserNameTaken(...)
User.exists(...)
User.lookup(...) != null
John Kugelman
źródło
0

Nazwy metod służą czytelności, najlepiej pasowałyby tylko te, które pasują do całego kodu, które w większości przypadków zaczynają się od warunków, więc subjectPredicate ma naturalną strukturę zdania.

Yuan
źródło
0

Dlaczego więc nie zmienić nazwy nieruchomości?

if (user.isPresent()) {
Artem Lukanin
źródło