Często spotykam błędy, które zostały spowodowane przez użycie ELSE
konstruktu. Doskonałym przykładem jest coś w stylu:
If (passwordCheck() == false){
displayMessage();
}else{
letThemIn();
}
Dla mnie to krzyczy problem bezpieczeństwa. Wiem, że PasswordCheck może być logiczną logiką, ale nie umieszczałbym na nim zabezpieczeń moich aplikacji. Co by się stało, gdyby to był ciąg znaków, int itp?
Zwykle staram się unikać używania ELSE
, a zamiast tego wybieram dwie całkowicie oddzielne instrukcje IF, aby sprawdzić, czego oczekuję. Cokolwiek innego wtedy zostanie zignorowane LUB zostanie specjalnie potraktowane.
Z pewnością jest to lepszy sposób na zapobieganie błędom / problemom z bezpieczeństwem w aplikacji.
Jak to robicie?
self-improvement
programming-practices
security
billy.bob
źródło
źródło
I know that passwordCheck is likely to be a boolean...
Co masz na myśli? W dowolnym silnym języku.passwordCheck
będzie co ty chcesz go mieć.else
instrukcji ...passwordCheck()
może nie być logiczny (co może być uzasadnionym problemem), a następnie obwiniasz goelse
? Nie rozumiem, jakie problemyelse
powodują.Odpowiedzi:
else
Blok zawsze powinien składać się z co chcesz domyślne zachowanie się.Nie musisz ich unikać, po prostu używaj ich odpowiednio.
W twoim przykładzie domyślnym stanem powinno być uniemożliwienie dostępu. Trochę refaktoryzacji pozostawia Ci:
tzn. jeśli sprawdzanie hasła działa, wpuść je, w przeciwnym razie zawsze jest ważny komunikat o błędzie.
Możesz oczywiście dodać dodatkowe kontrole do swojej logiki, używając
else if
raczej niż całkowicie osobnegoif
instrukcji.źródło
passwordCheck
może być cokolwiek, Fenull
, co czyniłobypasswordCheck == false
sięfalse
i by umożliwić użytkownikowi do logowania z powodu błędu wewnętrznego.if
wymaga abool
, zmienne muszą być definitywnie przypisane, wszystkie ścieżki muszą zwracać wartość itp., Nie mogę wymyślić żadnego powodu kolejnościif
ielse
miałby znaczenie oprócz czytelności. To znaczyif(a){b();}{c();}
powinno być równoważne zif(!a){c();{b();}
. Z drugiej strony w JavaScript musisz być świadomy, żepasswordCheck
może byćundefined
itp.Nie, nie ma w tym nic złego
ELSE
.ELSE
nie jest nowyGOTO
. W rzeczywistości, używając dwóchIF
s zamiastELSE
może prowadzić do kilku problemów.Przykład pierwszy:
Widzisz kopiowanie-wklej? Po prostu czeka na dzień, w którym zmienisz jedno i zapomnisz o drugim.
Przykład drugi:
Jak widać, drugi
IF
zostanie również wykonany dla pierwszego elementu, ponieważ warunek już się zmienił. W rzeczywistych programach takie błędy są trudniejsze do wykrycia.źródło
if
oświadczenie i odwracanie jego logiczną wyraz właśnie w celu uniknięciaelse
- teraz to jest złe programowanie! Nie tylko kopiujesz kod ( złe programowanie), ale także spowalniasz wydajność (jeśli sprawdzenie jest naprawdę skomplikowane, teraz robisz to dwa razy - ba ... no wiesz, co mówią o przedwczesnych optymalizacjach obecnie ... niezbyt dobre programowanie!).Zawsze jest ELSE. Jeśli napiszesz
faktycznie piszesz
Wszystko, co umieścisz na ścieżce ELSE, spoczywa na tobie.
źródło
Osobiście staram się unikać
else
jak najwięcej, ale to nie jest dla bezpieczeństwa problemu z .Podczas odczytywania kodu zagnieżdżone instrukcje utrudniają przestrzeganie logiki, ponieważ należy pamiętać, który zestaw warunków tam doprowadzi. Z tego powodu jestem wielkim fanem wczesnego wyjścia:
Dotyczy to również
for
iwhile
pętle, w których będę używałcontinue
ibreak
kiedy unika poziom wcięcia.Chris Lattner mówi to lepiej niż ja w standardach kodowania LLVM .
źródło
*writes an answer*
Następnie po prostu je zastąp
źródło
If ((passwordCheck == true) == true)
? :-)Podobnie jak Matthieu M., wolę wcześniejsze wyjście niż głęboko zagnieżdżone inne bloki ... To dobrze ilustruje programowanie obronne (jeśli złe warunki, nie ma sensu kontynuować). Wiele osób się z nami nie zgadza, preferując wyjątkowy punkt wyjścia; nie o to chodzi w debacie (tak myślę).
Teraz z pewnością używam,
else
gdy ma to sens, szczególnie w przypadku prostych, krótkich alternatyw. Jak powiedziano, powielanie testu jest stratą czasu (programisty i procesora), źródłem zamieszania, a później błędów (gdy jedno się zmienia, a nie drugie).Czasami dodaję komentarz do
else
części, przypominając o tym, co było warunkiem (szczególnie jeśliif
część jest długa, np. W starszym kodzie) lub jaka jest alternatywa.Zauważ, że niektórzy skrajni zwolennicy programowania funkcjonalnego proponują się go całkowicie pozbyć
if
, na rzecz dopasowania wzorców ... Trochę zbyt ekstremalnie jak na mój gust. :-)źródło
Nie ma nic złego w korzystaniu z ELSE. Może to jednak prowadzić do zbyt skomplikowanego kodu, który jest trudny do odczytania i zrozumienia. Może to oznaczać zły projekt. Z pewnością oznacza to dodatkowe przypadki użycia, które będą musiały zostać przetestowane.
Spróbuj usunąć ELSE, jeśli możesz - ale nie bądź na to paranoikiem. Steve McConnell nazywa ten kod linii prostej w Code Complete. Tj. Jest prosta prosta ścieżka przez twój kod.
Podejścia do wypróbowania konkretnego problemu:
Ogólnie rzecz biorąc - poniższe elementy mogą pomóc w ograniczeniu ELSE w kodzie:
źródło
Twoje przypuszczenie, że kod jest wyciekiem zabezpieczeń, może być lub nie być prawdziwe w zależności od używanego języka . W kodzie C może to być problem (szczególnie dlatego, że w C boolean jest tylko liczbą całkowitą niezerową lub zerową) - ale w najbardziej typowych językach (tj. Sprawdzanie typu środowiska wykonawczego), jeśli
passwordCheck
zmienna została zadeklarowana jako boolean, nie ma sposobu, aby przypisać coś innego. W rzeczywistości wszystko wif
predykacie musi zostać przetworzone na wartość logiczną, niezależnie od tego, czy używasz operatorów boolowskich, czy po prostu używasz wartości. Jeśli udało się powiązać inny typ obiektupasswordCheck
środowiskiem wykonawczym, wygenerowałby jakiś rodzaj nielegalnego wyjątku rzutowania.Proste konstrukcje if / else są znacznie łatwiejsze do odczytania niż konstrukcje if / if - i mniej podatne na nieumyślne problemy, jeśli ktoś spróbuje przerzucić konstrukt. Weźmy ten sam przykład przez sekundę:
Znaczenie wzajemnie wykluczających się klauzul, które chcesz wykonać powyżej, zostało utracone. To właśnie przekazuje konstrukcja if / else. Dwie wzajemnie wykluczające się gałęzie egzekucji, przy czym jedna z nich zawsze będzie działać. Jest to ważna część bezpieczeństwa - upewnienie się, że nie ma sposobu, aby
letThemIn
zadzwonićdenyAccess
.W celu zapewnienia przejrzystości kodu oraz w celu zapewnienia największej ochrony sekcji krytycznych powinny one znajdować się w klauzuli podstawowej (
if
części). Domyślne zachowanie niezgodne powinno znajdować się w alternatywnej klauzuli (else
części). Na przykład:UWAGA: pracując z różnymi językami, opracowałem nawyk kodowania, który pomaga uniknąć pytania „co jeśli to ciąg znaków?” Zasadniczo należy umieścić stałą na pierwszym miejscu w wyrażeniu boolowskim. Na przykład zamiast sprawdzania
passwordCheck == false
sprawdzamfalse == passwordCheck
. Pozwala to również uniknąć przypadkowego problemu przypisania możliwego w C ++. Przy takim podejściu kompilator będzie narzekał, jeśli piszę=
zamiast==
. W językach takich jak Java i C # kompilator traktowałby przypisanie w klauzuli if jako błąd, ale C ++ chętnie je zaakceptuje. Dlatego też mam tendencję do sprawdzania wartości zerowej przynull
pierwszym.Jeśli rutynowo zmieniasz języki, ustawianie stałej jako pierwszej jest bardzo pomocne. Jednak w moim zespole jest to sprzeczne ze standardem kodowania i kompilator i tak wychwytuje te problemy. Przełamanie może być trudne.
źródło
Mówiąc to za pomocą
else
podczas programowania jest złe, jest jak mówienie, że używanieotherwise
podczas mówienia jest złe.Oczywiście, oba mogą być używane w zły sposób, ale to nie znaczy, że należy ich unikać tylko dlatego, że popełniłeś błąd, który ich obejmował. Nie zdziwiłbym się, gdyby wiele błędów zależało od brakującej
default
sprawy wswitch
oświadczeniu.źródło
Pomyśl o
Else
białej liście przepływu aplikacji. Sprawdzasz warunki, które POWINNY umożliwić kontynuowanie przepływu aplikacji, a jeśli nie są spełnione, toElse
wykonywane jest zadanie rozwiązania problemu, przerwania wykonywania aplikacji lub coś podobnego.Else
samo w sobie nie jest złe, ale jeśli używasz go słabo, możesz zobaczyć niepożądane efekty.Również w odniesieniu do twojego oświadczenia o
„Wiem, że sprawdzanie hasła może być logiczne, ale nie umieszczałbym na nim zabezpieczeń moich aplikacji”.
W przypadku opracowywanych metod ZAWSZE zwracaj jeden typ danych. Chociaż PHP Core jest zaśmiecony kodem, który zwraca dwa lub więcej typów danych, jest to zła praktyka, ponieważ powoduje zgadywanie wywołań funkcji. Jeśli musisz zwrócić więcej niż jeden typ danych, zastanów się nad rzuceniem wyjątku (uważam, że często jest to powód, dla którego chciałbym zwrócić inny typ danych - coś poszło okropnie, okropnie źle) lub rozważyć zmianę struktury kodu, abyś mógł zwraca tylko jeden typ danych.
źródło
Po pierwsze. LOL! Nie ma żadnego powodu, aby unikać w ogóle. NIE jest to zła praktyka w żaden sposób, w żadnym kształcie ani formie.
Jeśli cokolwiek, kod powinien być
Nie ma dwóch, jeśli tam jest i nie ma nic innego. Tak robię we wszystkich moich aplikacjach oprócz tej, w której zgłaszam wyjątek. W mojej funkcji jest wychwytywany wyjątek, który sprawdza adres URL pod kątem wyświetlenia właściwej strony (lub alternatywnie mogę umieścić funkcję catch / check w funkcji błędu asp.net). Drukuje ogólną stronę z informacją, że nie autoryzuj lub jakąkolwiek wiadomość, której używam w wyjątku (zawsze sprawdzam typ wyjątku i ustawiam kod stanu HTTP).
-Edytuj- jak pokazano w przykładzie amunicji dwa, jeśli jest absurdalny. Naprawdę inne jest tak samo dobre lub lepsze niż if. Jeśli w ogóle należy tego unikać (chociaż ja osobiście tego nie robię, ale często używam return i break), ponieważ powiedziano, że więcej ścieżek kodu zwiększa prawdopodobieństwo błędów. Widzieć złożoność cykliczną
-Edycja 2- Jeśli martwisz się, czy użycie / else. Zauważę również, że wolę umieścić najkrótszy blok kodu na górze, taki jak
Zamiast
źródło
Kiedy mogę, mogę ustawić wartość domyślną przed warunkami warunkowymi. Wydaje mi się, że jest to trochę łatwiejsze do odczytania i bardziej jednoznaczne, ale to tylko preferencja. Mam tendencję do unikania negatywnych warunków w moim kodzie. Nie jestem wielkim fanem sprawdzania! Foo lub false == foo i wydaje mi się, że inaczej jest rodzajem warunkowego odpowiednika negatywu.
zamiast ...
Poprzedni blok kodu wydaje mi się trochę łatwiejszy do odczytania. Bardziej naturalna wydaje mi się sceptyczna paranoja dotycząca mojego kodu. Ustawienie wartości domyślnej niezależnie od warunków sprawia, że czuję się komfortowo: P
źródło
Twierdziłbym, że należy w jak największym stopniu unikać wszelkiego rodzaju logiki rozgałęziania. Chociaż nie ma nic złego w przypadku ELSE lub IF, istnieje wiele sposobów pisania kodu, aby zminimalizować potrzebę użycia dowolnej logiki rozgałęziającej. Nie twierdzę, że logikę rozgałęziania można całkowicie wyeliminować - będzie potrzebna w niektórych miejscach - ale możliwe jest przefakturowanie kodu, aby wyeliminować sporą jego część. W większości przypadków poprawi to zrozumiałość i dokładność kodu.
Na przykład operatorzy trójskładnikowi są zwykle dobrymi kandydatami:
Stosując podejście trójskładnikowe:
Operatorzy trójskładnikowi dobrze przesuwają rozgałęzienie w prawo.
źródło