Mam znajomego, bardziej doświadczonego programistę niż ja. Rozmawialiśmy o praktykach programistycznych i zaskoczyło mnie jego podejście do wypowiedzi „jeśli”. Nalega na pewne praktyki dotyczące stwierdzeń, które uważam za dość dziwne.
Po pierwsze , po instrukcji if powinna następować instrukcja else, niezależnie od tego, czy jest coś do wprowadzenia, czy nie. Co prowadzi do kodu wyglądającego tak:
if(condition)
{
doStuff();
return whatever;
}
else
{
}
Po drugie , lepiej jest sprawdzić prawdziwe wartości niż fałsz. Oznacza to, że lepiej jest przetestować zmienną „doorClosed” zamiast zmiennej „! DoorOpened”
Jego argumentem jest to, że sprawia, że jaśniejsze co kod robi.
Co mnie trochę dezorientuje, ponieważ połączenie tych dwóch reguł może doprowadzić go do napisania tego rodzaju kodu, jeśli chce coś zrobić, gdy warunek nie jest spełniony.
if(condition)
{
}
else
{
doStuff();
return whatever;
}
Mam wrażenie, że jest to naprawdę brzydkie i / lub poprawa jakości, jeśli w ogóle, jest znikoma. Ale jako junior jestem skłonny wątpić w mój instynkt.
Więc moje pytania brzmią: czy jest to dobra / zła / „nieważna” praktyka? Czy to powszechna praktyka?
źródło
Odpowiedzi:
Jawny
else
blokPierwsza reguła po prostu zanieczyszcza kod i sprawia, że nie jest on ani bardziej czytelny, ani mniej podatny na błędy. Przypuszczam, że celem twojego kolegi jest wyraźne, pokazując, że programista był w pełni świadomy, że warunek może się ocenić
false
. Chociaż dobrze jest być jawnym, taka jawność nie powinna kosztować trzech dodatkowych wierszy kodu .Nie wspominam nawet o tym, że po
if
oświadczeniu niekoniecznie musielse
znajdować się „ albo” albo „nic”: może też następować jeden lub więcejelif
.Obecność
return
oświadczenia pogarsza sytuację. Nawet jeśli faktycznie masz kod do wykonania welse
bloku, bardziej zrozumiałe będzie wykonanie tego w następujący sposób:To sprawia, że kod zajmuje dwa wiersze mniej, i odradza
else
blok. Chodzi o klauzule ochronne .Zauważ jednak, że technika twojego kolegi może częściowo rozwiązać bardzo nieprzyjemny wzór ułożonych bloków warunkowych bez spacji:
W poprzednim kodzie brak rozsądnego podziału linii po pierwszym
if
bloku bardzo łatwo źle interpretuje kod. Jednak chociaż reguła twojego kolegi utrudniłaby błędne odczytanie kodu, łatwiejszym rozwiązaniem byłoby po prostu dodanie nowego wiersza.Testuj
true
, a niefalse
Druga reguła może mieć jakiś sens, ale nie w obecnej formie.
Nie jest prawdą, że testowanie drzwi zamkniętych jest bardziej intuicyjne niż testowanie drzwi nieotwartych . Negacje, a zwłaszcza negacje zagnieżdżone, są zwykle trudne do zrozumienia:
Aby rozwiązać ten problem, zamiast dodawać puste bloki, utwórz dodatkowe właściwości, w stosownych przypadkach, lub zmienne lokalne .
Powyższy warunek można dość łatwo odczytać:
źródło
JZ
(Przełącz jeśli zero)if (foo)
doJNZ
(Przełącz jeśli nie zero)if (!foo)
.if
Jest już wyraźnie o tym, że stan może być fałszywe, albo nie będzie testowanie dla niego. Pusty blok sprawia, że wszystko jest mniej jasne, a nie więcej, ponieważ żaden czytelnik nie jest przygotowany, aby się tego spodziewać, a teraz muszą się zatrzymać i zastanowić, jak mógł się tam dostać.if (!commonCase) { handle the uncommon case },
.Jeśli chodzi o pierwszą zasadę, jest to przykład bezużytecznego pisania. Pisanie nie tylko zajmuje więcej czasu, ale powoduje ogromne zamieszanie dla osób czytających kod. Jeśli kod nie jest potrzebny, nie pisz go. Obejmuje to nawet brak wypełnienia
else
w twoim przypadku, gdy kod wraca zif
bloku:Jeśli chodzi o drugi punkt, dobrze jest unikać nazw boolowskich zawierających negatywne:
Jednak, jak zauważyłeś, rozszerzenie tego zakresu na brak testowania negatywu prowadzi do bardziej bezużytecznego pisania. Poniższe jest o wiele wyraźniejsze niż posiadanie pustego
if
bloku:źródło
if (!doorNotOpen)
jest okropny. Dlatego nazwy powinny być jak najbardziej pozytywne.if (! doorClosed)
jest całkowicie w porządku.doorNotOpen
nie jest to samo, ponieważdoorClosed
istnieje stan przejściowy między otwarciem a zamknięciem. Cały czas widzę to w moich aplikacjach przemysłowych, w których stany logiczne są określane przez czujniki fizyczne. Jeśli masz pojedynczy czujnik na otwartej stronie drzwi, możesz tylko powiedzieć, że drzwi są otwarte lub nie są otwarte. Podobnie, jeśli czujnik znajduje się po stronie zamkniętej, możesz powiedzieć tylko zamknięty lub nie zamknięty. Również sam czujnik określa sposób potwierdzania stanu logicznego.1. Argument za pustymi
else
stwierdzeniami.Często używam (i argumentuję) czegoś podobnego do tego pierwszego konstruktu, pustego innego. Sygnalizuje to czytelnikom kodu (zarówno ludzkim, jak i automatycznym narzędziom analitycznym), że programista zastanowił się nad sytuacją. Brakujące
else
oświadczenia, które powinny być obecne, zabijały ludzi, rozbijały pojazdy i kosztowały miliony dolarów. Na przykład MISRA-C nakazuje przynajmniej komentarz stwierdzający, że brakujący finał jest celowy wif (condition_1) {do_this;} else if (condition_2) {do_that;} ... else if (condition_n) {do_something_else;}
sekwencji. Inne standardy wysokiej niezawodności idą nawet dalej: z kilkoma wyjątkami, brak innych instrukcji jest zabronione.Jednym wyjątkiem jest prosty komentarz, coś podobnego do
/* Else not required */
. Sygnalizuje to ten sam cel, co trzy linie puste. Kolejnym wyjątkiem, w którym to puste miejsce nie jest potrzebne, jest oczywiste zarówno dla czytelników kodu, jak i dla automatycznych narzędzi analitycznych, które to puste zbędne. Na przykładif (condition) { do_stuff; return; }
Podobnie puste pole nie jest potrzebne w przypadkuthrow something
lubgoto some_label
1 zamiastreturn
.2. Argument za preferowanie
if (condition)
ponadif (!condition)
.To jest czynnik ludzki. Złożona logika boolowska wprawia w ruch wiele osób. Nawet doświadczony programista będzie musiał pomyśleć
if (!(complex || (boolean && condition))) do_that; else do_this;
. Przynajmniej przepisz to jakoif (complex || (boolean && condition)) do_this; else do_that;
.3. Nie oznacza to, że należy preferować puste
then
stwierdzenia.Druga sekcja mówi „wolisz” niż „powinieneś”. Jest to raczej wytyczna niż reguła. Powodem, dla którego wytyczne te preferują pozytywne
if
warunki, jest to, że kod powinien być jasny i oczywisty. Klauzula pusta wtedy (np.if (condition) ; else do_something;
) Narusza to. Jest to zaciemnione programowanie, które powoduje, że nawet najbardziej doświadczeni programiści wykonują kopie zapasowe i ponownie czytająif
stan w negowanej formie. Więc napisz to w negacji w pierwszej kolejności i pomiń instrukcję else (lub miej puste pole else lub komentarz na ten temat, jeśli jest do tego upoważniony).1 pisałem, że wtedy klauzule, które kończą się
return
,throw
czygoto
nie wymagają pusty indziej. Oczywiste jest, że klauzula else nie jest potrzebna. Ale co zgoto
? Nawiasem mówiąc, zasady programowania krytyczne dla bezpieczeństwa czasami zabraniają wczesnego powrotu i prawie zawsze nie dopuszczają wyjątków. Pozwalają jednakgoto
na to w ograniczonej formie (npgoto cleanup1;
.). To ograniczone użyciegoto
jest preferowaną praktyką w niektórych miejscach. Na przykład jądro Linuksa jest pełne takichgoto
instrukcji.źródło
!
również łatwo przeoczyć. To jest zbyt zwięzłe.else { /* Intentionally empty */ }
coś w tym stylu. To, co puste, spełnia wymagania analizatora statycznego, który bezmyślnie szuka naruszeń zasad. Komentarz informuje czytelników, że puste inne jest zamierzone. Z drugiej strony, doświadczeni programiści zwykle pomijają komentarz jako niepotrzebny - ale nie jest pusty. Programowanie o wysokiej niezawodności jest domeną samą w sobie. Konstrukty wyglądają raczej dziwnie dla osób postronnych. Te konstrukty są używane z powodu lekcji ze szkoły mocnych uderzeń, uderzeń, które są bardzo trudne, gdy życie i śmierć lub $$$$$$$$$ są pod ręką.if (target == source) then /* we need to do nothing */ else updateTarget(source)
not
podobnie jak inne operatory bitowe i logiczne , jest słowem kluczowym w C ++. Zobacz alternatywne reprezentacje operatorów .Używam pustej gałęzi else (a czasem pustej gałęzi if) w bardzo rzadkich przypadkach: gdy jest oczywiste, że zarówno część if, jak i część powinny być obsługiwane w jakiś sposób, ale z jakiegoś nietrywialnego powodu sprawa może być obsługiwana przez nic nie robić. Dlatego każdy, kto czyta kod z koniecznym działaniem else, natychmiast podejrze, że czegoś brakuje i zmarnuje swój czas.
Ale nie:
źródło
if test succeeds -> no action needed -> else -> action needed
jest semantycznie bardzo różna od instrukcjiif it applies that the opposite of a test outcome is true then an action is needed
. Przypomina mi się cytat Martina Fowlera: „każdy może pisać kod, który komputery rozumieją; dobrzy programiści piszą kod, który ludzie rozumieją”.if ((missing || corrupt) && !backup) -> skip -> else do stuff
Jest o wiele jaśniejsze (+ inne dorozumiane zamiary) niżif ((!missing && !corrupt) || backup) -> do stuff
if(!((missing || corrupt) && !backup)) -> do stuff
lub lepiejif((aviable && valid) || backup) -> do stuff
. (Ale w prawdziwym przykładzie przed użyciem należy sprawdzić, czy kopia zapasowa jest ważna)if
:file_ok = !missing && !corrupt; if(file_ok || backup) do_stuff();
co, moim zdaniem, sprawia, że jest jeszcze wyraźniej.Wszystkie pozostałe są równe, wolę zwięzłość.
Czego nie piszesz, nikt nie musi czytać i rozumieć.
Chociaż wyraźne może być przydatne, dzieje się tak tylko wtedy, gdy bez nadmiernej gadatliwości stanie się oczywiste, że to, co napisałeś, jest naprawdę tym, co chciałeś napisać.
Unikaj więc pustych gałęzi, są one nie tylko bezużyteczne, ale także rzadkie i prowadzą do zamieszania.
Unikaj także pisania gałęzi else, jeśli wyjdziesz bezpośrednio z gałęzi if.
Przydatnym zastosowaniem jawności byłoby umieszczenie komentarza za każdym razem, gdy przejdziemy przez skrzynkę przełączników
// FALLTHRU
, oraz użycie komentarza lub pustego bloku, w którym potrzebujesz pustej instrukcjifor(a;b;c) /**/;
.źródło
// FALLTHRU
Ugh, nie w SCREAMING CAPS lub w skrótach txtspk. W przeciwnym razie sam się zgadzam i stosuję tę praktykę.break
. Brak,break
który doprowadził do spektakularnych awarii oprogramowania. Dobrym pomysłem jest komentarz, który krzyczy czytelnikom kodu, że celowe przejście jest celowe. To, że narzędzia analizy statycznej mogą szukać tego konkretnego wzorca i nie narzekać na kryzys, czyni go jeszcze lepszym.vim
i nie rozpoznaje żadnej odmianyFALLTHRU
. I myślę, że nie bez powodu:TODO
aFIXME
komentarze są komentarze, które muszą być grepable, ponieważ chcemy, aby móc zapytaćgit grep
, które znane wady masz w kodzie, a gdzie są one zlokalizowane. Kryzys nie jest wadą i nie ma powodu, by się za niego żałować.FALLTHRU
, nie oznacza, że inni ludzie nie skonfigurowali vima, aby to zrobić.Według mojej wiedzy nie ma twardych i szybkich zasad dotyczących pozytywnych lub negatywnych warunków dla instrukcji IF. Osobiście wolę kodowanie dla przypadku pozytywnego niż negatywnego, w stosownych przypadkach. Z pewnością tego nie zrobię, jeśli doprowadzi mnie to do utworzenia pustego bloku JEŻELI, po którym następuje ELSE pełen logiki. Gdyby taka sytuacja się pojawiła, zajęłoby to 3 sekundy, aby powrócić do testowania pod kątem pozytywnego przypadku.
To, co naprawdę nie lubię w twoich przykładach, to całkowicie niepotrzebna przestrzeń pionowa zajmowana przez pusty ELSE. Po prostu nie ma po temu żadnego powodu. Nie dodaje niczego do logiki, nie pomaga dokumentować tego, co robi kod, i wcale nie zwiększa czytelności. W rzeczywistości argumentowałbym, że dodana przestrzeń pionowa mogłaby prawdopodobnie zmniejszyć czytelność.
źródło
if(hasWriteAccess(user,file))
może być skomplikowane, ale na pierwszy rzut oka wiesz dokładnie, jaki powinien być wynik. Nawet jeśli jest to tylko kilka warunków, np.if(user.hasPermission() && !file.isLocked())
Wywołanie metody o odpowiedniej nazwie ma sens, więc negatywy stają się mniejszym problemem.Jawny
else
blokNie zgadzam się z tym jako ogólne stwierdzenie obejmujące wszystkie
if
stwierdzenia, ale zdarza się, że dodanieelse
bloku z przyzwyczajenia jest dobrą rzeczą.if
Oświadczenie, moim zdaniem, w rzeczywistości obejmuje dwie odrębne funkcje.Jeśli mamy coś zrobić, zrób to tutaj.
Takie rzeczy oczywiście nie wymagają
else
części.aw niektórych przypadkach naleganie na dodanie
else
może wprowadzić w błąd.to nie to samo co
nawet jeśli jest funkcjonalnie taki sam. Pisanie pierwszego
if
z pustymelse
może doprowadzić do drugiego wyniku, który jest niepotrzebnie brzydki.Jeśli sprawdzamy konkretny stan, często dobrym pomysłem jest dodanie pustego,
else
aby przypomnieć o sytuacjiPamiętaj, że te zasady obowiązują tylko podczas pisania nowego kodu . IMHO Puste
else
klauzule powinny zostać usunięte przed odprawą.Testuj
true
, a niefalse
Ponownie jest to dobra rada na poziomie ogólnym, ale w wielu przypadkach powoduje to, że kod jest niepotrzebnie złożony i mniej czytelny.
Mimo że kod podobny
denerwuje czytelnika, ale robi to
jest co najmniej tak źle, jeśli nie gorzej.
I kodowane w BCPL wiele lat temu iw tym języku istnieje
IF
klauzula iUNLESS
klauzula więc można kodować wiele bardziej czytelnie jako:co jest znacznie lepsze, ale wciąż nie idealne.
Mój osobisty proces
Zasadniczo, gdy piszę nowy kod, często dodaję pusty
else
blok doif
instrukcji, aby przypomnieć mi, że nie opisałem jeszcze tej ewentualności. Pomaga mi to uniknąćDFS
pułapki i zapewnia, że kiedy przeglądam kod, zauważam, że jest więcej do zrobienia. Zazwyczaj jednak dodajęTODO
komentarz, aby śledzić.Uważam, że generalnie
else
rzadko używam w kodzie, ponieważ często może to wskazywać na zapach kodu.źródło
unless
Blok to dobra propozycja, a ledwie ograniczone do BCPL....
było w rzeczywistościreturn
. (W rzeczywistości, zk=-1
,n=-2
pierwszy powrót jest brany, ale jest to w dużej mierze dyskusyjne.)if
iunless
. Co więcej, umożliwia to również po oświadczeniu, dzięki czemu możesz powiedziećprint "Hello world!" if $born;
lubprint "Hello world!" unless $dead;
oba zrobią dokładnie to, co według ciebie robią.Po pierwsze, użyłem języka, który wymusił użycie instrukcji IF w ten sposób (w Opal, język za skrobaczką do ekranu głównego do umieszczania interfejsu użytkownika GUI w systemach mainframe) i tylko z jedną linią dla IF i ELSE. To nie było przyjemne doświadczenie!
Spodziewałbym się, że każdy kompilator zoptymalizuje takie dodatkowe klauzule ELSE. Ale w przypadku kodu na żywo nic nie dodaje (w fazie rozwoju może być użytecznym znacznikiem dla dalszego kodu).
Czasem używam czegoś takiego jak te dodatkowe klauzule, kiedy używam przetwarzania typu CASE / WHEN. Zawsze dodam domyślną klauzulę, nawet jeśli jest pusta. Jest to długotrwały nawyk ze strony języków, które popełniają błąd, jeśli taka klauzula nie zostanie użyta, i zmusza do zastanowienia się, czy rzeczy naprawdę powinny po prostu przejść.
Dawno temu praktyka na komputerach mainframe (np. PL / 1 i COBOL) została przyjęta, że kontrole negatywne były mniej skuteczne. To może wyjaśnić drugi punkt, chociaż w dzisiejszych czasach są znacznie ważniejsze oszczędności wydajności, które są ignorowane jako mikrooptymalizacje.
Negatywna logika bywa mniej czytelna, choć nie tak bardzo w przypadku tak prostej instrukcji IF.
źródło
if !A then B; else C
sięif A then C; else B
. Obliczanie negacji warunku jest dodatkową instrukcją procesora. (Chociaż, jak mówisz, jest mało prawdopodobne, aby było to znacznie mniej wydajne.)!
i==
operatorami. Nie chodzi o to, że ktoś powinien to robić , pamiętajcie o tym ...Oparłbym stanowisko większości odpowiedzi, że puste
else
bloki są praktycznie zawsze szkodliwym marnotrawstwem atramentu elektronicznego. Nie dodawaj ich, chyba że masz ku temu dobry powód, w którym to przypadku pusty blok wcale nie powinien być pusty, powinien zawierać komentarz wyjaśniający, dlaczego tak jest.Problem unikania negatywów zasługuje jednak na większą uwagę: zazwyczaj, gdy trzeba użyć wartości logicznej, potrzebujesz bloków kodu do działania, gdy jest on ustawiony, oraz innych bloków do działania, gdy nie jest ustawiony. W związku z tym, jeśli wymusisz regułę nieujemną, wymuszasz albo posiadanie
if() {} else {...}
instrukcji (z pustymif
blokiem!), Albo tworzysz drugą wartość logiczną dla każdej wartości logicznej, która zawiera jej zanegowaną wartość. Obie opcje są złe, ponieważ dezorientują czytelników.Pomocna zasada jest taka: Nigdy nie używaj zanegowanej formy w nazwie logicznej i wyrażaj negację jako pojedynczą
!
. Takie zdanieif(!doorLocked)
jest całkowicie jasne, takie jakif(!doorUnlocked)
mózg węzłów. Późniejszy rodzaj wyrażenia to rzecz, której należy unikać za wszelką cenę, a nie obecność jednego!
w danymif()
stanie.źródło
Powiedziałbym, że to zdecydowanie zła praktyka. Dodanie innych instrukcji spowoduje dodanie do kodu całego szeregu bezcelowych wierszy, które nic nie robią, a jeszcze bardziej utrudnią ich odczytanie.
źródło
Jest jeszcze jeden wzorzec, który nie został jeszcze wspomniany na temat obsługi drugiego przypadku, który ma pusty blok if. Jednym ze sposobów radzenia sobie z tym jest powrót do bloku if. Lubię to:
Jest to powszechny wzorzec sprawdzania warunków błędów. Przypadek twierdzący jest nadal używany, a jego wnętrze nie jest już puste, co pozwala przyszłym programistom zastanawiać się, czy rezygnacja nie była zamierzona. Może także poprawić czytelność, ponieważ może być konieczne utworzenie nowej funkcji (dzielenie dużych funkcji na mniejsze indywidualne funkcje).
źródło
Rozważając argument „zawsze mam inną klauzulę”, jest jeden punkt, którego nie widziałem w żadnej innej odpowiedzi: może mieć sens w funkcjonalnym stylu programowania. Raczej.
W funkcjonalnym stylu programowania operujesz wyrażeniami, a nie wyrażeniami. Zatem każdy blok kodu ma wartość zwracaną - w tym
if-then-else
wyrażenie. Wykluczałoby to jednak pustyelse
blok. Dam ci przykład:Teraz w językach ze składnią w stylu C lub inspirowaną stylem C (takich jak Java, C # i JavaScript, żeby wymienić tylko kilka), wygląda to dziwnie. Wygląda jednak znacznie lepiej, gdy jest napisany jako taki:
Pozostawienie
else
tutaj pustej gałęzi spowodowałoby, że wartość byłaby niezdefiniowana - w większości przypadków nie jest to prawidłowy przypadek podczas programowania funkcji. To samo z całkowitym pominięciem. Jednak, gdy programujesz iteracyjnie, mam bardzo mało powodów, aby zawsze miećelse
blok.źródło
Nie zgadzam się, że
if (a) { } else { b(); }
powinienem być przepisany jakoif (!a) { b(); }
iif (a) { b(); } else { }
powinien zostać przepisany jakoif (a) { b(); }
.Warto jednak zaznaczyć, że rzadko mam pustą gałąź. Jest tak, ponieważ normalnie loguję, że wszedłem do innej pustej gałęzi. W ten sposób mogę opracować wyłącznie komunikaty dziennika. Rzadko używam debugera. W środowiskach produkcyjnych nie ma debugera; miło jest móc rozwiązywać problemy produkcyjne za pomocą tych samych narzędzi, których używasz do programowania.
Mam mieszane uczucia na ten temat. Wadą posiadania
doorClosed
idoorOpened
potencjalnie podwojenia liczby słów / terminów, o których musisz wiedzieć. Kolejną wadą jest z czasem znaczeniedoorClosed
idoorOpened
może się zmieniać (inni programiści przychodzą za tobą) i możesz skończyć z dwiema właściwościami, które nie są już dokładnymi zaprzeczeniami. Zamiast unikać negacji, cenię sobie dostosowanie języka kodu (nazw klas, nazw zmiennych itp.) Do słownictwa użytkowników biznesowych i do wymagań, które otrzymałem. Nie chciałbym wymyślać zupełnie nowego terminu, aby uniknąć!
jeśli termin ten ma znaczenie tylko dla programisty, którego użytkownicy biznesowi nie zrozumieją. Chcę, aby programiści mówili tym samym językiem, co użytkownicy i osoby piszące wymagania. Teraz, jeśli nowe warunki upraszczają model, to ważne, ale należy się tym zająć przed sfinalizowaniem wymagań, a nie później. Projektanci powinni poradzić sobie z tym problemem, zanim zaczną kodować.Dobrze jest nadal zadawać sobie pytania.
Do pewnego stopnia wiele z tego nie ma znaczenia. Sprawdź kod i dostosuj się do swojego zespołu. Zazwyczaj jest to właściwe. Jeśli wszyscy w twoim zespole chcą kodować w określony sposób, prawdopodobnie najlepiej to zrobić w ten sposób (zmiana 1 osoby - ciebie - zajmuje mniej punktów historii niż zmiana grupy ludzi).
Nie pamiętam, żeby widziałem pustą gałąź. Jednak widzę ludzi dodających właściwości, aby uniknąć negacji.
źródło
Zajmę się tylko drugą częścią pytania, a to wynika z mojego punktu widzenia pracy w systemach przemysłowych i manipulowania urządzeniami w prawdziwym świecie.
Jest to jednak w pewnym sensie rozszerzony komentarz, a nie odpowiedź.
Kiedy jest powiedziane
Z mojego punktu widzenia przyjmuje się tutaj założenie, że stan drzwi jest stanem binarnym, podczas gdy w rzeczywistości jest to przynajmniej stan potrójny:
Zatem w zależności od tego, gdzie znajduje się pojedynczy, binarny czujnik cyfrowy, można przypuszczać tylko jedną z dwóch koncepcji:
I nie można wymieniać tych pojęć za pomocą binarnej negacji. Tak więc
doorClosed
i!doorOpened
prawdopodobnie nie są synonimami, a każda próba udawania, że są synonimami, jest błędnym myśleniem, które zakłada większą wiedzę o stanie systemu niż w rzeczywistości istnieje.Wracając do twojego pytania, poparłbym verbage, które pasuje do źródła informacji reprezentowanej przez zmienną. Tak więc, jeśli informacje pochodzą z zamkniętej strony drzwi, należy przejść z
doorClosed
itd. Może to oznaczać użycie jednegodoorClosed
lub!doorClosed
w razie potrzeby w różnych oświadczeniach zgodnie z wymaganiami, co może spowodować potencjalne pomylenie z użyciem negacji. Ale to, czego nie robi, to pośrednio propaguje założenia dotyczące stanu systemu.Do celów dyskusji na temat mojej pracy ilość dostępnych informacji o stanie systemu zależy od funkcjonalności wymaganej przez sam system.
Czasami muszę tylko wiedzieć, czy drzwi są zamknięte, czy nie zamknięte. W takim przypadku wystarczy pojedynczy czujnik binarny. Ale innym razem muszę wiedzieć, że drzwi są otwarte, zamknięte lub w trakcie przejścia. W takich przypadkach byłyby albo dwa czujniki binarne (na każdym krańcu ruchu drzwi - z kontrolą błędów przy jednoczesnym otwieraniu i zamykaniu drzwi) lub istniałby czujnik analogowy mierzący, jak „otwarte” były drzwi.
Przykładem pierwszego są drzwi do kuchenki mikrofalowej. Umożliwiają działanie piekarnika w zależności od tego, czy drzwiczki są zamknięte lub nie są zamknięte. Nie obchodzi cię, jak otwarte są drzwi.
Przykładem drugiego może być prosty siłownik napędzany silnikiem. Uniemożliwia się napędzanie silnika do przodu, gdy siłownik jest całkowicie wysunięty. I hamujesz napędzanie silnika do tyłu, gdy siłownik jest całkowicie włączony.
Zasadniczo liczba i rodzaj czujników sprowadza się do przeprowadzenia analizy kosztów czujników względem analizy wymagań dotyczących tego, co jest potrzebne do osiągnięcia wymaganej funkcjonalności.
źródło
Konkretne reguły stylu są zawsze złe. Wytyczne są dobre, ale w końcu często zdarza się, że możesz zrobić coś jaśniejszego, robiąc coś, co nie jest zgodne z wytycznymi.
To powiedziawszy, jest wiele nienawiści do pustych jeszcze „marnuje linie” „dodatkowego pisania”, które są po prostu złe. Możesz argumentować za przeniesieniem nawiasów na tę samą linię, jeśli naprawdę potrzebujesz przestrzeni pionowej, ale jeśli to jest problem, nie powinieneś umieszczać {w osobnej linii.
Jak wspomniano w innym miejscu, blok else jest bardzo przydatny, aby pokazać, że wyraźnie nie chcesz, aby nic się nie wydarzyło w innym przypadku. Po zrobieniu dużo programowania funkcjonalnego (gdzie jest to wymagane), nauczyłem się, że zawsze powinieneś brać pod uwagę inne przy pisaniu if, chociaż, jak wspomina @OldCurmudgeon, istnieją naprawdę dwa różne przypadki użycia. Trzeba mieć coś innego, nie należy. Niestety, nie jest to coś, co zawsze można powiedzieć na pierwszy rzut oka, nie mówiąc już o wkładce, stąd dogmatyczne „zawsze stawiaj inny blok”.
Jeśli chodzi o „brak negatywów”, ponownie, bezwzględne zasady są złe. Posiadanie pustego, jeśli może być dziwne, szczególnie jeśli jest to rodzaj, jeśli nie potrzebuje innego, więc pisz to wszystko, a nie! lub an == fałsz jest zły. To powiedziawszy, istnieje wiele przypadków, w których negatywne ma sens. Typowym przykładem może być buforowanie wartości:
jeśli rzeczywista (mentalna / angielska) logika obejmuje negatywne, to samo powinno być w przypadku instrukcji if.
źródło